ConcurrentSkipListMap深入分析
1.前言
ConcurrentHashMap與ConcurrentSkipListMap性能測試
在4線程1.6萬數據的條件下,ConcurrentHashMap 存取速度是ConcurrentSkipListMap 的4倍左右。但ConcurrentSkipListMap有幾個ConcurrentHashMap 不能比擬的優點:
-
ConcurrentSkipListMap 的key是有序的。
-
ConcurrentSkipListMap 支持更高的并發。ConcurrentSkipListMap 的存取時間是log(N),和線程數幾乎無關。也就是說在數據量一定的情況下,并發的線程越多,ConcurrentSkipListMap越能體現出他 的優勢
2.使用建議
在非多線程的情況下,應當盡量使用TreeMap。此外對于并發性相對較低的并行程序可以使用 Collections.synchronizedSortedMap將TreeMap進行包裝,也可以提供較好的效率。對于高并發程序,應當使用 ConcurrentSkipListMap,能夠提供更高的并發度。
所以在多線程程序中,如果需要對Map的鍵值進行排序時,請盡量使用ConcurrentSkipListMap,可能得到更好的并發度。
注意,調用ConcurrentSkipListMap的size時,由于多個線程可以同時對映射表進行操作,所以映射表需要遍歷整個鏈表才能返回元素個數,這個操作是個O(log(n))的操作。
?3.什么是SkipList
Skiplist(跳表)是一種可以代替平衡樹的數據結構,默認是按照Key值升序的。Skiplist讓已排序的數據分布在多層鏈表中,以0-1隨機數決定一個數據的向上攀升與否,通過“空間來換取時間”的一個算法,在每個節點中增加了向前的指針,在插入、刪除、查找時可以忽略一些不可能涉及到的結點,從而提高了效率。
從概率上保持數據結構的平衡比顯示的保持數據結構平衡要簡單的多。對于大多數應用,用Skip list要比用樹算法相對簡單。由于Skip list比較簡單,實現起來會比較容易,雖然和平衡樹有著相同的時間復雜度(O(logn)),但是skip list的常數項會相對小很多。Skiplist在空間上也比較節省。一個節點平均只需要1.333個指針(甚至更少)。
? ? ? ? ? ? ? ??
圖1-1 Skip list結構圖(以7,14,21,32,37,71,85序列為例)
Skip list的性質
(1) 由很多層結構組成,level是通過一定的概率隨機產生的。
(2) 每一層都是一個有序的鏈表,默認是升序,也可以根據創建映射時所提供的Comparator進行排序,具體取決于使用的構造方法。
(3) 最底層(Level 1)的鏈表包含所有元素。
(4) 如果一個元素出現在Level i 的鏈表中,則它在Level i 之下的鏈表也都會出現。
(5) 每個節點包含兩個指針,一個指向同一鏈表中的下一個元素,一個指向下面一層的元素。
三、什么是ConcurrentSkipListMap
?
ConcurrentSkipListMap提供了一種線程安全的并發訪問的排序映射表。內部是SkipList(跳表)結構實現,在理論上能夠在O(log(n))時間內完成查找、插入、刪除操作。
???? ? 注意,調用ConcurrentSkipListMap的size時,由于多個線程可以同時對映射表進行操作,所以映射表需要遍歷整個鏈表才能返回元素個數,這個操作是個O(log(n))的操作。
?ConcurrentSkipListMap存儲結構
ConcurrentSkipListMap存儲結構圖
?
跳躍表(SkipList):(如上圖所示)
1.多條鏈構成,是關鍵字升序排列的數據結構;
2.包含多個級別,一個head引用指向最高的級別,最低(底部)的級別,包含所有的key;
3.每一個級別都是其更低級別的子集,并且是有序的;
4.如果關鍵字 key在 級別level=i中出現,則,level<=i的鏈表中都會包含該關鍵字key;
------------------------
ConcurrentSkipListMap主要用到了Node和Index兩種節點的存儲方式,通過volatile關鍵字實現了并發的操作
??
[java]?view plaincopy?
?
------------------------
ConcurrentSkipListMap的查找
通過SkipList的方式進行查找操作:(下圖以“查找91”進行說明:)
?
紅色虛線,表示查找的路徑,藍色向右箭頭表示right引用;黑色向下箭頭表示down引用;
?
/get方法,通過doGet操作實現
?
[java]?view plaincopy?
?
?
------------------------------------------------
ConcurrentSkipListMap的刪除
通過SkipList的方式進行刪除操作:(下圖以“刪除23”進行說明:)
?
紅色虛線,表示查找的路徑,藍色向右箭頭表示right引用;黑色向下箭頭表示down引用;
?
?
[java]?view plaincopy
?
-------------------------------------
?
ConcurrentSkipListMap的插入
?
?
通過SkipList的方式進行插入操作:(下圖以“添加55”的兩種情況,進行說明:)
在level=2(該level存在)的情況下添加55的圖示:只需在level<=2的合適位置插入55即可
--------
在level=4(該level不存在,圖示level4是新建的)的情況下添加55的情況:首先新建level4,然后在level<=4的合適位置插入55
-----------
?
[java]?view plaincopy轉載于:https://www.cnblogs.com/wxgblogs/p/5465218.html
總結
以上是生活随笔為你收集整理的ConcurrentSkipListMap深入分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android被逼学习例子2
- 下一篇: java 中对对象的调用