摘要:我們來看下的類繼承圖可以看到,實現了接口,在多線程進階二五之框架中,我們提到過實現了接口,以提供和排序相關的功能,維持元素的有序性,所以就是一種為并發環境設計的有序工具類。唯一的區別是針對的僅僅是鍵值,針對鍵值對進行操作。
本文首發于一世流云專欄:https://segmentfault.com/blog...一、ConcurrentSkipListSet簡介
ConcurrentSkipListSet,是JDK1.6時J.U.C新增的一個集合工具類,顧名思義,它是一種SET類型。
SET類型,在數學上稱為“集合”,具有互異性、無序性的特點,也就是說SET中的任意兩個元素均不相同(即不包含重復元素),且元素是無序的。
是不是感覺和HashMap有點類似?HashMap中的Key也是不能重復,且是無序的。
事實上,JDK提供的默認SET實現——HashSet,其實就是采用“組合”的方式——內部引用了一個HashMap對象,以此實現SET的功能。
我們來看下ConcurrentSkipListSet的類繼承圖:
可以看到,ConcurrentSkipListSet實現了NavigableSet接口,在Java多線程進階(二五)—— J.U.C之collections框架:ConcurrentSkipListMap中,我們提到過ConcurrentSkipListMap實現了NavigableMap接口,以提供和排序相關的功能,維持元素的有序性,所以ConcurrentSkipListSet就是一種為并發環境設計的有序SET工具類。
NavigableSet的功能和NavigableMap幾乎是完全一樣的,提供了根據指定Key返回最接近項、按升序/降序返回所有鍵的視圖等功能。唯一的區別是NavigableSet針對的僅僅是鍵值,NavigableMap針對鍵值對進行操作。二、ConcurrentSkipListSet原理 內部結構
ConcurrentSkipListSet的實現非常簡單,其內部引用了一個ConcurrentSkipListMap對象,所有API方法均委托ConcurrentSkipListMap對象完成:
public class ConcurrentSkipListSetextends AbstractSet implements NavigableSet , Cloneable, java.io.Serializable { /** * The underlying map. Uses Boolean.TRUE as value for each * element. This field is declared final for the sake of thread * safety, which entails some ugliness in clone(). */ private final ConcurrentNavigableMap m; public ConcurrentSkipListSet() { m = new ConcurrentSkipListMap (); } public ConcurrentSkipListSet(Comparator super E> comparator) { m = new ConcurrentSkipListMap (comparator); } public ConcurrentSkipListSet(Collection extends E> c) { m = new ConcurrentSkipListMap (); addAll(c); } public ConcurrentSkipListSet(SortedSet s) { m = new ConcurrentSkipListMap (s.comparator()); addAll(s); } ConcurrentSkipListSet(ConcurrentNavigableMap m) { this.m = m; } // ... }
從上述代碼可以看出,ConcurrentSkipListSet在構造時創建了一個ConcurrentSkipListMap對象,并由字段m引用,所以其實ConcurrentSkipListSet就是一種跳表類型的數據結構,其平均增刪改查的時間復雜度均為O(logn)。
核心方法我們來看下ConcurrentSkipListSet是如何實現API方法的:
public int size() { return m.size(); } public boolean isEmpty() { return m.isEmpty(); } public boolean contains(Object o) { return m.containsKey(o); } public boolean add(E e) { return m.putIfAbsent(e, Boolean.TRUE) == null; } public boolean remove(Object o) { return m.remove(o, Boolean.TRUE); } public void clear() { m.clear(); } ? //...
從上述代碼可以看出,所有操作均是委托ConcurrentSkipListMap對象完成的。重點看下add方法:
public boolean add(E e) { return m.putIfAbsent(e, Boolean.TRUE) == null; }
我們知道ConcurrentSkipListMap對鍵值對的要求是均不能為null,所以ConcurrentSkipListSet在插入元素的時候,用一個Boolean.TRUE對象(相當于一個值為true的Boolean型對象)作為value,同時putIfAbsent可以保證不會存在相同的Key。
所以,最終跳表中的所有Node結點的Key均不會相同,且值都是Boolean.True。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/76941.html
摘要:同時,也提供了一個基于的實現類,底層基于紅黑樹設計,是一種有序的。可以看成是并發版本的,但是和不同是,并不是基于紅黑樹實現的,其底層是一種類似跳表的結構。上述所有構造器都調用了方法方法將一些字段置初始化,然后將指針指向新創建的結點。 showImg(https://segmentfault.com/img/remote/1460000016201159); 本文首發于一世流云專欄:ht...
摘要:整個包,按照功能可以大致劃分如下鎖框架原子類框架同步器框架集合框架執行器框架本系列將按上述順序分析,分析所基于的源碼為。后,根據一系列常見的多線程設計模式,設計了并發包,其中包下提供了一系列基礎的鎖工具,用以對等進行補充增強。 showImg(https://segmentfault.com/img/remote/1460000016012623); 本文首發于一世流云專欄:https...
摘要:僅僅當有多個線程同時進行寫操作時,才會進行同步。可以看到,上述方法返回一個迭代器對象,的迭代是在舊數組上進行的,當創建迭代器的那一刻就確定了,所以迭代過程中不會拋出并發修改異常。另外,迭代器對象也不支持修改方法,全部會拋出異常。 showImg(https://segmentfault.com/img/bVbggij?w=960&h=600); 本文首發于一世流云專欄:https://...
摘要:我們之前已經介紹過了,底層基于跳表實現,其操作平均時間復雜度均為。事實上,內部引用了一個對象,以組合方式,委托對象實現了所有功能。線程安全內存的使用較多迭代是對快照進行的,不會拋出,且迭代過程中不支持修改操作。 showImg(https://segmentfault.com/img/bVbggjf?w=600&h=377); 本文首發于一世流云專欄:https://segmentfa...
摘要:接口截止目前為止,我們介紹的阻塞隊列都是實現了接口。該類在構造時一般需要指定容量,如果不指定,則最大容量為。另外,由于內部通過來保證線程安全,所以的整體實現時比較簡單的。另外,雙端隊列相比普通隊列,主要是多了隊尾出隊元素隊首入隊元素的功能。 showImg(https://segmentfault.com/img/bVbgZ7j?w=770&h=514); 本文首發于一世流云專欄:ht...
閱讀 1759·2021-11-11 16:55
閱讀 2545·2021-08-27 13:11
閱讀 3622·2019-08-30 15:53
閱讀 2301·2019-08-30 15:44
閱讀 1378·2019-08-30 11:20
閱讀 1036·2019-08-30 10:55
閱讀 943·2019-08-29 18:40
閱讀 3029·2019-08-29 16:13