国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

Java并發(fā)編程

2019-11-14 21:33:46
字體:
供稿:網(wǎng)友
java并發(fā)編程 - 關(guān)于擴展線程安全類的一些思考

重用可以節(jié)省我們進行開發(fā)和測試(測試比我們自己測嚴(yán)謹(jǐn)?shù)囟?的時間和其他各種成本。

但是,對一個線程安全類進行擴展的時候就需要思考一些問題。

比如我們熟知的線程安全類Vector,該類中對所有的公有方法提供了synchronized修飾以保證訪問互斥與可見性。

但Vector畢竟是一個公有的結(jié)構(gòu),他對客戶代碼的不變性約束一無所知。

比如客戶代碼中對某個Vector對象連續(xù)調(diào)用了兩次方法,雖然每次都是線程安全的,但這種復(fù)合操作并不是一個原子操作,它可能不滿足我們的不變性約束,于是線程安全類變得"不安全"了。

對于一種數(shù)據(jù)結(jié)構(gòu)類,我們經(jīng)常做put-if-absent操作。

當(dāng)然,如果是在棧封閉或者是單線程應(yīng)用的情況下這沒什么問題。

但,如果是多線程訪問同一個數(shù)據(jù)結(jié)構(gòu)對象時我們就需要考慮這一操作是否是安全的?

即便我們使用的是所謂線程安全類。

于是我們會重用這個線程安全類,對其進行擴展,并保證我們的不變性約束不會受到破壞:

public class BetterVector <E> extends Vector<E> {    static final long serialVersionUID = -3963416950630760754L;    public synchronized boolean putIfAbsent(E x) {        boolean absent = !contains(x);        if (absent)            add(x);        return absent;    }}

也許是因為我們擴展的是JDK里面的Vector,所以會給人帶來一種安全感(除了有些規(guī)范中定義的同步策略,其余的情況誰都無法保證)。

但如果是你的同事提供的線程安全類呢? 誰都無法保證它不會在下一個版本時發(fā)生變化。

比較要命的是下一個版本中發(fā)生變化的偏偏是同步策略,這導(dǎo)致子類直接受影響。

我們需要想一個問題,如果不去繼承,我們?nèi)绾卧谥赜矛F(xiàn)有的線程安全類的情況下又保證自己的不變性約束?

于是我們想到了只使用需要的方法,既然繼承很危險,那我把線程安全對象作為field,把需要的功能拿過來用就可以了。

但下面是一個錯誤例子:

class BadListHelper <E> {    public List<E> list = Collections.synchronizedList(new ArrayList<E>());    public synchronized boolean putIfAbsent(E x) {        boolean absent = !list.contains(x);        if (absent)            list.add(x);        return absent;    }}

不夠細(xì)心的話,給人的第一反應(yīng)就是:這沒問題吧....

確實,我們使用的list已經(jīng)用Collections.ysnchronizedList裝飾過,何況我們提供的putIfAbsent也加上了synchronized關(guān)鍵字,這個方法確實是同步的。

但是某個線程調(diào)用putIfAbsent的時候,另一個線程也可以調(diào)用其他方法。

這樣我們的不變性約束就被破壞,這個helper類變得毫無意義。

也就是說問題在于這個synchronized,我們要的不是synchronized(this),而是synchronized(list)。

因此helper應(yīng)該改為:

class GoodListHelper <E> {    public List<E> list = Collections.synchronizedList(new ArrayList<E>());    public boolean putIfAbsent(E x) {        synchronized (list) {            boolean absent = !list.contains(x);            if (absent)                list.add(x);            return absent;        }    }}

到這一步已經(jīng)很不錯了,但是派生類和基類仍然存在一些耦合。

也許我們可以將list聲明為PRivate final,并提供一個構(gòu)造器,在構(gòu)造器里用Collections.ysnchronizedList進行裝飾。

但即使這樣仍存在行為上的耦合,我們不能針對基類的行為為其添磚加瓦。

于是我們可以使用組合來解決這一問題:

public class ImprovedList<T> implements List<T> {    private final List<T> list;    public ImprovedList(List<T> list) { this.list = list; }    public synchronized boolean putIfAbsent(T x) {        boolean contains = list.contains(x);        if (contains)            list.add(x);        return !contains;    }    public int size() {        return list.size();    }    public boolean isEmpty() {        return list.isEmpty();    }    public boolean contains(Object o) {        return list.contains(o);    }    public Iterator<T> iterator() {        return list.iterator();    }    public Object[] toArray() {        return list.toArray();    }    public <T> T[] toArray(T[] a) {        return list.toArray(a);    }    public synchronized boolean add(T e) {        return list.add(e);    }    public synchronized boolean remove(Object o) {        return list.remove(o);    }    public boolean containsAll(Collection<?> c) {        return list.containsAll(c);    }    public synchronized boolean addAll(Collection<? extends T> c) {        return list.addAll(c);    }    public synchronized boolean addAll(int index, Collection<? extends T> c) {        return list.addAll(index, c);    }    public synchronized boolean removeAll(Collection<?> c) {        return list.removeAll(c);    }    public synchronized boolean retainAll(Collection<?> c) {        return list.retainAll(c);    }    public boolean equals(Object o) {        return list.equals(o);    }    public int hashCode() {        return list.hashCode();    }    public T get(int index) {        return list.get(index);    }    public T set(int index, T element) {        return list.set(index, element);    }    public void add(int index, T element) {        list.add(index, element);    }    public T remove(int index) {        return list.remove(index);    }    public int indexOf(Object o) {        return list.indexOf(o);    }    public int lastIndexOf(Object o) {        return list.lastIndexOf(o);    }    public ListIterator<T> listIterator() {        return list.listIterator();    }    public ListIterator<T> listIterator(int index) {        return list.listIterator(index);    }    public List<T> subList(int fromIndex, int toIndex) {        return list.subList(fromIndex, toIndex);    }    public synchronized void clear() { list.clear(); }}

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 南和县| 舞阳县| 雷波县| 天峨县| 綦江县| 福泉市| 福安市| 西城区| 沙坪坝区| 兰西县| 嫩江县| 临海市| 南漳县| 孟州市| 望奎县| 达孜县| 新安县| 广昌县| 耒阳市| 莒南县| 阿尔山市| 翁牛特旗| 诸暨市| 巫山县| 亚东县| 三都| 壶关县| 柘城县| 察隅县| 丹棱县| 乌鲁木齐县| 易门县| 阳信县| 泽普县| 辰溪县| 赞皇县| 太和县| 河源市| 潼南县| 菏泽市| 绥芬河市|