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)

posted @ 2015-01-18 15:00  K太狼  阅读(5644)  评论(0编辑  收藏  举报