ConcrrentSkipListMap介紹和原理分析


一、前言:

JDK為我們提供了很多Map接口的實現,使得我們可以方便地處理Key-Value的數據結構。

當我們希望快速存取<Key, Value>鍵值對時我們可以使用HashMap。

當我們希望在多線程並發存取<Key, Value>鍵值對時,我們會選擇ConcurrentHashMap。

TreeMap則會幫助我們保證數據是按照Key的自然順序或者compareTo方法指定的排序規則進行排序。

OK,那么當我們需要多線程並發存取<Key, Value>數據並且希望保證數據有序時,我們需要怎么做呢?

。。。。。。

也許,我們可以選擇ConcurrentTreeMap。不好意思,JDK沒有提供這么好的數據結構給我們。

當然,我們可以自己添加lock來實現ConcurrentTreeMap,但是隨着並發量的提升,lock帶來的性能開銷也隨之增大。

Don't cry......,JDK6里面引入的ConcurrentSkipListMap也許可以滿足我們的需求。

JDK Documentation對ConcurrentSkipListMap的介紹


通過上面的介紹我們可以對ConcurrentSkipListMap中基本操作的時間復雜度有個基本的了解:

Operation Time Complexity
Insertion O(log N)
Removal O(log N)
Check if contains O(log N)
Enumerate in order O(N)

 

 

 

 

 

二、ConcurrentSkipListMap實例:

 

 1 import java.util.Iterator;
 2 import java.util.NavigableSet;
 3 import java.util.concurrent.ConcurrentNavigableMap;
 4 import java.util.concurrent.ConcurrentSkipListMap;
 5 
 6 public class ConcurrentSkipListMapExample {
 7     public static void main(String[] args) {
 8         ConcurrentNavigableMap<String, String> concurrentSkipListMap = new ConcurrentSkipListMap<String, String>();
 9         concurrentSkipListMap.put("3", "Wednesday");
10         concurrentSkipListMap.put("2", "Tuesday");
11         concurrentSkipListMap.put("1", "Monday");
12         concurrentSkipListMap.put("5", "Friday");
13         concurrentSkipListMap.put("4", "Thursday");
14         
15         NavigableSet<String> navigableSet = concurrentSkipListMap.descendingKeySet();
16         System.out.println("descendingKeySet: ");
17         Iterator<String> itr = navigableSet.iterator();
18         while (itr.hasNext()) {
19             String s = itr.next();
20             System.out.println(s);
21         }
22         System.out.println("ceilingEntry-2: " + concurrentSkipListMap.ceilingEntry("2"));
23         System.out.println("firstEntry: " + concurrentSkipListMap.firstEntry());
24         System.out.println("lastEntry: " + concurrentSkipListMap.lastEntry());
25         System.out.println("pollFirstEntry: " + concurrentSkipListMap.pollFirstEntry());
26         System.out.println("now firstEntry: " + concurrentSkipListMap.firstEntry());
27         System.out.println("pollLastEntry: " + concurrentSkipListMap.pollLastEntry());
28         System.out.println("now lastEntry: " + concurrentSkipListMap.lastEntry());
29         System.out.println("Entry-2: " + concurrentSkipListMap.get("2"));
30     }
31 
32 }

 

三、ConcurrentSkipListMap性能測試:

下面,我們來比較一下ConcurrentSkipListMap與TreeMap在並發情況下查詢的性能狀況。

我們會啟動n個線程隨機讀取Map中的記錄,每個線程會讀取106次。

從測試結果,我們可以看出隨着並發度的不斷提高,ConcurrentSkipListMap相對於TreeMap的優勢也越來越明顯。

四、ConcurrentSkipListMap實現原理

skiplist數據結構介紹:

http://kenby.iteye.com/blog/1187303

concurrentskiplistmap實現並發的原理:

concurrentskiplistmap並沒有使用lock來保證線程的並發訪問和修改,而是使用了非阻塞算法來保證並發訪問(Michael-Scott 算法)

也可以參考下面的博客(http://blog.csdn.net/jy3161286/article/details/22809913)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM