ConcurrentSkipListMap/Set 基于跳表的Map和Set

Java并发包中与TreeMap/TreeSet对应的并发版本是ConcurrentSkipListMap和ConcurrentSkipListSet

 

TreeSet是基于TreeMap实现的,与此类似,ConcurrentSkipListSet也是基于ConcurrentSkipListMap实现的

ConcurrentSkipListMap是基于SkipList实现的,SkipList称为跳跃表或跳表,是一种数据结构。并发版本为什么采用跳表而不是树呢?原因也很简单,因为跳表更易于实现高效并发算法。ConcurrentSkipListMap有如下特点。

1)没有使用锁,所有操作都是无阻塞的,所有操作都可以并行,包括写,多线程可以同时写。

2)与ConcurrentHashMap类似,迭代器不会抛出ConcurrentModificationException,是弱一致的,迭代可能反映最新修改也可能不反映,一些方法如putAll、clear不是原子的。

3)与ConcurrentHashMap类似,同样实现了ConcurrentMap接口,支持一些原子复合操作。

4)与TreeMap一样,可排序,默认按键的自然顺序,也可以传递比较器自定义排序,实现了SortedMap和NavigableMap接口。

看段简单的使用代码:

public static void main(String[] args) {
    Map<String, String> map = new ConcurrentSkipListMap<>(Collections.reverseOrder());
    map.put("a", "abstract");
    map.put("c", "call");
    map.put("b", "basic");
    System.out.println(map.toString());
}

程序输出为:

{c=call, b=basic, a=abstract}

表示是有序的。

需要说明的是ConcurrentSkipListMap的size方法,与大多数容器实现不同,这个方法不是常量操作,它需要遍历所有元素,复杂度为O(N),而且遍历结束后,元素个数可能已经变了。一般而言,在并发应用中,这个方法用处不大。

 

参考: Java编程的逻辑 17.3 基于跳表的Map和Set

 

上一篇:D3.JS v5 画矩阵图


下一篇:集合(24):Map集合案例