摘要:我們之前已經介紹過了,底層基于跳表實現,其操作平均時間復雜度均為。事實上,內部引用了一個對象,以組合方式,委托對象實現了所有功能。線程安全內存的使用較多迭代是對快照進行的,不會拋出,且迭代過程中不支持修改操作。
本文首發于一世流云專欄:https://segmentfault.com/blog...一、CopyOnWriteArraySet簡介
CopyOnWriteArraySet,是另一類適合并發環境的SET工具類,也是在JDK1.5時,隨著J.U.C包一起引入的。
我們之前已經介紹過了ConcurrentSkipListSet,ConcurrentSkipListSet底層基于Skip List(跳表)實現,其操作平均時間復雜度均為O(logn)。
CopyOnWriteArraySet,從名字上可以看出,也是基于“寫時復制”的思想。事實上,CopyOnWriteArraySet內部引用了一個CopyOnWriteArrayList對象,以“組合”方式,委托CopyOnWriteArrayList對象實現了所有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是如何實現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); }
可以看到,上述所有的方法都是通過委托實現的,唯一的區別就是CopyOnWriteArraySet不允許含有重復元素,所以添加元素(add方法)時,內部調用了CopyOnWriteArrayList的addAllAbsent方法。
三、總結既然CopyOnWriteArraySet也是基于“寫時復制”的思想,那么它的特性也和CopyOnWriteArrayList是類似的,歸結起來,有以下幾點:
適合“讀多寫少”且數據量不大的場景。
線程安全
內存的使用較多
迭代是對快照進行的,不會拋出ConcurrentModificationException,且迭代過程中不支持修改操作。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/76939.html
摘要:僅僅當有多個線程同時進行寫操作時,才會進行同步。可以看到,上述方法返回一個迭代器對象,的迭代是在舊數組上進行的,當創建迭代器的那一刻就確定了,所以迭代過程中不會拋出并發修改異常。另外,迭代器對象也不支持修改方法,全部會拋出異常。 showImg(https://segmentfault.com/img/bVbggij?w=960&h=600); 本文首發于一世流云專欄:https://...
摘要:整個包,按照功能可以大致劃分如下鎖框架原子類框架同步器框架集合框架執行器框架本系列將按上述順序分析,分析所基于的源碼為。后,根據一系列常見的多線程設計模式,設計了并發包,其中包下提供了一系列基礎的鎖工具,用以對等進行補充增強。 showImg(https://segmentfault.com/img/remote/1460000016012623); 本文首發于一世流云專欄:https...
摘要:我們來看下的類繼承圖可以看到,實現了接口,在多線程進階二五之框架中,我們提到過實現了接口,以提供和排序相關的功能,維持元素的有序性,所以就是一種為并發環境設計的有序工具類。唯一的區別是針對的僅僅是鍵值,針對鍵值對進行操作。 showImg(https://segmentfault.com/img/bVbggic?w=960&h=600); 本文首發于一世流云專欄:https://seg...
摘要:接口截止目前為止,我們介紹的阻塞隊列都是實現了接口。該類在構造時一般需要指定容量,如果不指定,則最大容量為。另外,由于內部通過來保證線程安全,所以的整體實現時比較簡單的。另外,雙端隊列相比普通隊列,主要是多了隊尾出隊元素隊首入隊元素的功能。 showImg(https://segmentfault.com/img/bVbgZ7j?w=770&h=514); 本文首發于一世流云專欄:ht...
摘要:在章節中,我們說過,維護了一把全局鎖,無論是出隊還是入隊,都共用這把鎖,這就導致任一時間點只有一個線程能夠執行。入隊鎖對應的是條件隊列,出隊鎖對應的是條件隊列,所以每入隊一個元素,應當立即去喚醒可能阻塞的其它入隊線程。 showImg(https://segmentfault.com/img/bVbgCD9?w=1920&h=1080); 本文首發于一世流云專欄:https://seg...
閱讀 1172·2021-11-24 09:39
閱讀 2675·2021-09-28 09:35
閱讀 1070·2019-08-30 15:55
閱讀 1361·2019-08-30 15:44
閱讀 880·2019-08-29 17:00
閱讀 1969·2019-08-29 12:19
閱讀 3311·2019-08-28 18:28
閱讀 690·2019-08-28 18:10