摘要:我們之前已經(jīng)介紹過了,底層基于跳表實現(xiàn),其操作平均時間復(fù)雜度均為。事實上,內(nèi)部引用了一個對象,以組合方式,委托對象實現(xiàn)了所有功能。線程安全內(nèi)存的使用較多迭代是對快照進(jìn)行的,不會拋出,且迭代過程中不支持修改操作。
本文首發(fā)于一世流云專欄:https://segmentfault.com/blog...一、CopyOnWriteArraySet簡介
CopyOnWriteArraySet,是另一類適合并發(fā)環(huán)境的SET工具類,也是在JDK1.5時,隨著J.U.C包一起引入的。
我們之前已經(jīng)介紹過了ConcurrentSkipListSet,ConcurrentSkipListSet底層基于Skip List(跳表)實現(xiàn),其操作平均時間復(fù)雜度均為O(logn)。
CopyOnWriteArraySet,從名字上可以看出,也是基于“寫時復(fù)制”的思想。事實上,CopyOnWriteArraySet內(nèi)部引用了一個CopyOnWriteArrayList對象,以“組合”方式,委托CopyOnWriteArrayList對象實現(xiàn)了所有API功能。
public class CopyOnWriteArraySet二、CopyOnWriteArraySet原理extends AbstractSet implements java.io.Serializable { private final CopyOnWriteArrayList al; /** * Creates an empty set. */ public CopyOnWriteArraySet() { al = new CopyOnWriteArrayList (); } public CopyOnWriteArraySet(Collection extends E> c) { if (c.getClass() == CopyOnWriteArraySet.class) { CopyOnWriteArraySet cc = (CopyOnWriteArraySet ) c; al = new CopyOnWriteArrayList (cc.al); } else { al = new CopyOnWriteArrayList (); al.addAllAbsent(c); } } // ... }
我們來看下CopyOnWriteArraySet是如何實現(xiàn)API接口的功能的:
public int size() { return al.size(); } public boolean isEmpty() { return al.isEmpty(); } public boolean contains(Object o) { return al.contains(o); } public Object[] toArray() { return al.toArray(); } publicT[] toArray(T[] a) { return al.toArray(a); } public void clear() { al.clear(); } public boolean remove(Object o) { return al.remove(o); } public boolean add(E e) { return al.addIfAbsent(e); } public boolean containsAll(Collection> c) { return al.containsAll(c); } public boolean addAll(Collection extends E> c) { return al.addAllAbsent(c) > 0; } public boolean removeAll(Collection> c) { return al.removeAll(c); } public boolean retainAll(Collection> c) { return al.retainAll(c); } public Iterator iterator() { return al.iterator(); } public boolean removeIf(Predicate super E> filter) { return al.removeIf(filter); } public void forEach(Consumer super E> action) { al.forEach(action); }
可以看到,上述所有的方法都是通過委托實現(xiàn)的,唯一的區(qū)別就是CopyOnWriteArraySet不允許含有重復(fù)元素,所以添加元素(add方法)時,內(nèi)部調(diào)用了CopyOnWriteArrayList的addAllAbsent方法。
三、總結(jié)既然CopyOnWriteArraySet也是基于“寫時復(fù)制”的思想,那么它的特性也和CopyOnWriteArrayList是類似的,歸結(jié)起來,有以下幾點:
適合“讀多寫少”且數(shù)據(jù)量不大的場景。
線程安全
內(nèi)存的使用較多
迭代是對快照進(jìn)行的,不會拋出ConcurrentModificationException,且迭代過程中不支持修改操作。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/76939.html
摘要:僅僅當(dāng)有多個線程同時進(jìn)行寫操作時,才會進(jìn)行同步??梢钥吹剑鲜龇椒ǚ祷匾粋€迭代器對象,的迭代是在舊數(shù)組上進(jìn)行的,當(dāng)創(chuàng)建迭代器的那一刻就確定了,所以迭代過程中不會拋出并發(fā)修改異常。另外,迭代器對象也不支持修改方法,全部會拋出異常。 showImg(https://segmentfault.com/img/bVbggij?w=960&h=600); 本文首發(fā)于一世流云專欄:https://...
摘要:整個包,按照功能可以大致劃分如下鎖框架原子類框架同步器框架集合框架執(zhí)行器框架本系列將按上述順序分析,分析所基于的源碼為。后,根據(jù)一系列常見的多線程設(shè)計模式,設(shè)計了并發(fā)包,其中包下提供了一系列基礎(chǔ)的鎖工具,用以對等進(jìn)行補(bǔ)充增強(qiáng)。 showImg(https://segmentfault.com/img/remote/1460000016012623); 本文首發(fā)于一世流云專欄:https...
摘要:我們來看下的類繼承圖可以看到,實現(xiàn)了接口,在多線程進(jìn)階二五之框架中,我們提到過實現(xiàn)了接口,以提供和排序相關(guān)的功能,維持元素的有序性,所以就是一種為并發(fā)環(huán)境設(shè)計的有序工具類。唯一的區(qū)別是針對的僅僅是鍵值,針對鍵值對進(jìn)行操作。 showImg(https://segmentfault.com/img/bVbggic?w=960&h=600); 本文首發(fā)于一世流云專欄:https://seg...
摘要:接口截止目前為止,我們介紹的阻塞隊列都是實現(xiàn)了接口。該類在構(gòu)造時一般需要指定容量,如果不指定,則最大容量為。另外,由于內(nèi)部通過來保證線程安全,所以的整體實現(xiàn)時比較簡單的。另外,雙端隊列相比普通隊列,主要是多了隊尾出隊元素隊首入隊元素的功能。 showImg(https://segmentfault.com/img/bVbgZ7j?w=770&h=514); 本文首發(fā)于一世流云專欄:ht...
摘要:在章節(jié)中,我們說過,維護(hù)了一把全局鎖,無論是出隊還是入隊,都共用這把鎖,這就導(dǎo)致任一時間點只有一個線程能夠執(zhí)行。入隊鎖對應(yīng)的是條件隊列,出隊鎖對應(yīng)的是條件隊列,所以每入隊一個元素,應(yīng)當(dāng)立即去喚醒可能阻塞的其它入隊線程。 showImg(https://segmentfault.com/img/bVbgCD9?w=1920&h=1080); 本文首發(fā)于一世流云專欄:https://seg...
閱讀 1183·2021-11-24 09:39
閱讀 2688·2021-09-28 09:35
閱讀 1082·2019-08-30 15:55
閱讀 1376·2019-08-30 15:44
閱讀 886·2019-08-29 17:00
閱讀 1983·2019-08-29 12:19
閱讀 3319·2019-08-28 18:28
閱讀 701·2019-08-28 18:10