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接口。
看段简单的使用代码:
1 2 3 4 5 6 7 | 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()); } |
程序输出为:
1 | {c=call, b=basic, a= abstract } |
表示是有序的。
需要说明的是ConcurrentSkipListMap的size方法,与大多数容器实现不同,这个方法不是常量操作,它需要遍历所有元素,复杂度为O(N),而且遍历结束后,元素个数可能已经变了。一般而言,在并发应用中,这个方法用处不大。
参考: Java编程的逻辑 17.3 基于跳表的Map和Set
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步