摘要:介紹底層是通過來(lái)實(shí)現(xiàn)的,它是一個(gè)有序的線程安全的集合。源碼分析它的源碼比較簡(jiǎn)單,跟通過實(shí)現(xiàn)的基本是一致,只是多了一些取最近的元素的方法。
介紹
ConcurrentSkipListSet底層是通過ConcurrentNavigableMap來(lái)實(shí)現(xiàn)的,它是一個(gè)有序的線程安全的集合。
源碼分析它的源碼比較簡(jiǎn)單,跟通過Map實(shí)現(xiàn)的Set基本是一致,只是多了一些取最近的元素的方法。
// 實(shí)現(xiàn)了NavigableSet接口,并沒有所謂的ConcurrentNavigableSet接口 public class ConcurrentSkipListSetextends AbstractSet implements NavigableSet , Cloneable, java.io.Serializable { private static final long serialVersionUID = -2479143111061671589L; // 存儲(chǔ)使用的map private final ConcurrentNavigableMap m; // 初始化 public ConcurrentSkipListSet() { m = new ConcurrentSkipListMap (); } // 傳入比較器 public ConcurrentSkipListSet(Comparator super E> comparator) { m = new ConcurrentSkipListMap (comparator); } // 使用ConcurrentSkipListMap初始化map // 并將集合c中所有元素放入到map中 public ConcurrentSkipListSet(Collection extends E> c) { m = new ConcurrentSkipListMap (); addAll(c); } // 使用ConcurrentSkipListMap初始化map // 并將有序Set中所有元素放入到map中 public ConcurrentSkipListSet(SortedSet s) { m = new ConcurrentSkipListMap (s.comparator()); addAll(s); } // ConcurrentSkipListSet類內(nèi)部返回子set時(shí)使用的 ConcurrentSkipListSet(ConcurrentNavigableMap m) { this.m = m; } // 克隆方法 public ConcurrentSkipListSet clone() { try { @SuppressWarnings("unchecked") ConcurrentSkipListSet clone = (ConcurrentSkipListSet ) super.clone(); clone.setMap(new ConcurrentSkipListMap (m)); return clone; } catch (CloneNotSupportedException e) { throw new InternalError(); } } /* ---------------- Set operations -------------- */ // 返回元素個(gè)數(shù) public int size() { return m.size(); } // 檢查是否為空 public boolean isEmpty() { return m.isEmpty(); } // 檢查是否包含某個(gè)元素 public boolean contains(Object o) { return m.containsKey(o); } // 添加一個(gè)元素 // 調(diào)用map的putIfAbsent()方法 public boolean add(E e) { return m.putIfAbsent(e, Boolean.TRUE) == null; } // 移除一個(gè)元素 public boolean remove(Object o) { return m.remove(o, Boolean.TRUE); } // 清空所有元素 public void clear() { m.clear(); } // 迭代器 public Iterator iterator() { return m.navigableKeySet().iterator(); } // 降序迭代器 public Iterator descendingIterator() { return m.descendingKeySet().iterator(); } /* ---------------- AbstractSet Overrides -------------- */ // 比較相等方法 public boolean equals(Object o) { // Override AbstractSet version to avoid calling size() if (o == this) return true; if (!(o instanceof Set)) return false; Collection> c = (Collection>) o; try { // 這里是通過兩次兩層for循環(huán)來(lái)比較 // 這里是有很大優(yōu)化空間的,參考上篇文章CopyOnWriteArraySet中的彩蛋 return containsAll(c) && c.containsAll(this); } catch (ClassCastException unused) { return false; } catch (NullPointerException unused) { return false; } } // 移除集合c中所有元素 public boolean removeAll(Collection> c) { // Override AbstractSet version to avoid unnecessary call to size() boolean modified = false; for (Object e : c) if (remove(e)) modified = true; return modified; } /* ---------------- Relational operations -------------- */ // 小于e的最大元素 public E lower(E e) { return m.lowerKey(e); } // 小于等于e的最大元素 public E floor(E e) { return m.floorKey(e); } // 大于等于e的最小元素 public E ceiling(E e) { return m.ceilingKey(e); } // 大于e的最小元素 public E higher(E e) { return m.higherKey(e); } // 彈出最小的元素 public E pollFirst() { Map.Entry e = m.pollFirstEntry(); return (e == null) ? null : e.getKey(); } // 彈出最大的元素 public E pollLast() { Map.Entry e = m.pollLastEntry(); return (e == null) ? null : e.getKey(); } /* ---------------- SortedSet operations -------------- */ // 取比較器 public Comparator super E> comparator() { return m.comparator(); } // 最小的元素 public E first() { return m.firstKey(); } // 最大的元素 public E last() { return m.lastKey(); } // 取兩個(gè)元素之間的子set public NavigableSet subSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) { return new ConcurrentSkipListSet (m.subMap(fromElement, fromInclusive, toElement, toInclusive)); } // 取頭子set public NavigableSet headSet(E toElement, boolean inclusive) { return new ConcurrentSkipListSet (m.headMap(toElement, inclusive)); } // 取尾子set public NavigableSet tailSet(E fromElement, boolean inclusive) { return new ConcurrentSkipListSet (m.tailMap(fromElement, inclusive)); } // 取子set,包含from,不包含to public NavigableSet subSet(E fromElement, E toElement) { return subSet(fromElement, true, toElement, false); } // 取頭子set,不包含to public NavigableSet headSet(E toElement) { return headSet(toElement, false); } // 取尾子set,包含from public NavigableSet tailSet(E fromElement) { return tailSet(fromElement, true); } // 降序set public NavigableSet descendingSet() { return new ConcurrentSkipListSet (m.descendingMap()); } // 可分割的迭代器 @SuppressWarnings("unchecked") public Spliterator spliterator() { if (m instanceof ConcurrentSkipListMap) return ((ConcurrentSkipListMap )m).keySpliterator(); else return (Spliterator )((ConcurrentSkipListMap.SubMap )m).keyIterator(); } // 原子更新map,給clone方法使用 private void setMap(ConcurrentNavigableMap map) { UNSAFE.putObjectVolatile(this, mapOffset, map); } // 原子操作相關(guān)內(nèi)容 private static final sun.misc.Unsafe UNSAFE; private static final long mapOffset; static { try { UNSAFE = sun.misc.Unsafe.getUnsafe(); Class> k = ConcurrentSkipListSet.class; mapOffset = UNSAFE.objectFieldOffset (k.getDeclaredField("m")); } catch (Exception e) { throw new Error(e); } } }
可以看到,ConcurrentSkipListSet基本上都是使用ConcurrentSkipListMap實(shí)現(xiàn)的,雖然取子set部分是使用ConcurrentSkipListMap中的內(nèi)部類,但是這些內(nèi)部類其實(shí)也是和ConcurrentSkipListMap相關(guān)的,它們返回ConcurrentSkipListMap的一部分?jǐn)?shù)據(jù)。
總結(jié)(1)ConcurrentSkipListSet底層是使用ConcurrentNavigableMap實(shí)現(xiàn)的;
(2)ConcurrentSkipListSet有序的,基于元素的自然排序或者通過比較器確定的順序;
(3)ConcurrentSkipListSet是線程安全的;
Set大匯總Set | 有序性 | 線程安全 | 底層實(shí)現(xiàn) | 關(guān)鍵接口 | 特點(diǎn) |
---|---|---|---|---|---|
HashSet | 無(wú) | 否 | HashMap | 無(wú) | 簡(jiǎn)單 |
LinkedHashSet | 有 | 否 | LinkedHashMap | 無(wú) | 插入順序 |
TreeSet | 有 | 否 | NavigableMap | NavigableSet | 自然順序 |
CopyOnWriteArraySet | 有 | 是 | CopyOnWriteArrayList | 無(wú) | 插入順序,讀寫分離 |
ConcurrentSkipListSet | 有 | 是 | ConcurrentNavigableMap | NavigableSet | 自然順序 |
從中我們可以發(fā)現(xiàn)一些規(guī)律:
除了HashSet其它Set都是有序的;
實(shí)現(xiàn)了NavigableSet或者SortedSet接口的都是自然順序的;
使用并發(fā)安全的集合實(shí)現(xiàn)的Set也是并發(fā)安全的;
TreeSet雖然不是全部都是使用的TreeMap實(shí)現(xiàn)的,但其實(shí)都是跟TreeMap相關(guān)的(TreeMap的子Map中組合了TreeMap);
ConcurrentSkipListSet雖然不是全部都是使用的ConcurrentSkipListMap實(shí)現(xiàn)的,但其實(shí)都是跟ConcurrentSkipListMap相關(guān)的(ConcurrentSkipListeMap的子Map中組合了ConcurrentSkipListMap);
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/76265.html
摘要:我們來(lái)看下的類繼承圖可以看到,實(shí)現(xiàn)了接口,在多線程進(jìn)階二五之框架中,我們提到過實(shí)現(xiàn)了接口,以提供和排序相關(guān)的功能,維持元素的有序性,所以就是一種為并發(fā)環(huán)境設(shè)計(jì)的有序工具類。唯一的區(qū)別是針對(duì)的僅僅是鍵值,針對(duì)鍵值對(duì)進(jìn)行操作。 showImg(https://segmentfault.com/img/bVbggic?w=960&h=600); 本文首發(fā)于一世流云專欄:https://seg...
摘要:介紹底層是使用存儲(chǔ)元素的,所以它并不是使用來(lái)存儲(chǔ)元素的。最簡(jiǎn)單的方式就是判斷是否中的元素都在中,中的元素是否都在中,也就是兩次兩層循環(huán)。其實(shí),并不需要。標(biāo)記某個(gè)元素是否找到過,防止重復(fù)這個(gè)位置沒找到過才比較大小 介紹 CopyOnWriteArraySet底層是使用CopyOnWriteArrayList存儲(chǔ)元素的,所以它并不是使用Map來(lái)存儲(chǔ)元素的。 但是,我們知道CopyOnWri...
摘要:源碼分析屬性內(nèi)部使用虛擬對(duì)象,用來(lái)作為放到中構(gòu)造方法非,主要是給使用的構(gòu)造方法都是調(diào)用對(duì)應(yīng)的構(gòu)造方法。遍歷元素直接調(diào)用的的迭代器。什么是機(jī)制是集合中的一種錯(cuò)誤機(jī)制。當(dāng)使用迭代器迭代時(shí),如果發(fā)現(xiàn)集合有修改,則快速失敗做出響應(yīng),拋出異常。 簡(jiǎn)介 集合,這個(gè)概念有點(diǎn)模糊。 廣義上來(lái)講,java中的集合是指java.util包下面的容器類,包括和Collection及Map相關(guān)的所有類。 中...
摘要:純分享直接上干貨操作系統(tǒng)并發(fā)支持進(jìn)程管理內(nèi)存管理文件系統(tǒng)系統(tǒng)進(jìn)程間通信網(wǎng)絡(luò)通信阻塞隊(duì)列數(shù)組有界隊(duì)列鏈表無(wú)界隊(duì)列優(yōu)先級(jí)有限無(wú)界隊(duì)列延時(shí)無(wú)界隊(duì)列同步隊(duì)列隊(duì)列內(nèi)存模型線程通信機(jī)制內(nèi)存共享消息傳遞內(nèi)存模型順序一致性指令重排序原則內(nèi)存語(yǔ)義線程 純分享 , 直接上干貨! 操作系統(tǒng)并發(fā)支持 進(jìn)程管理內(nèi)存管...
摘要:就有這個(gè)功能,它是怎么實(shí)現(xiàn)有序的呢源碼分析繼承自,讓我們直接上源碼來(lái)看看它們有什么不同。是有序的,它是按照插入的順序排序的。所以,是不支持按訪問順序?qū)υ嘏判虻?,只能按插入順序排序? 介紹 上一節(jié)我們說(shuō)HashSet中的元素是無(wú)序的,那么有沒有什么辦法保證Set中的元素是有序的呢? 答案是當(dāng)然可以。 LinkedHashSet就有這個(gè)功能,它是怎么實(shí)現(xiàn)有序的呢? 源碼分析 Linked...
閱讀 2850·2021-10-13 09:48
閱讀 3851·2021-10-13 09:39
閱讀 3628·2021-09-22 16:04
閱讀 1872·2021-09-03 10:48
閱讀 875·2021-08-03 14:04
閱讀 2386·2019-08-29 15:18
閱讀 3443·2019-08-26 12:19
閱讀 2899·2019-08-26 12:08