ConcurrentSkipListSet和ConcurrentSkipListMap分析以及总结Set

ConcurrentSkipListSet和ConcurrentSkipListMap分析以及总结Set

ConcurrentSkipListSet怎么实现线程安全

跳表结构

跳表是一种概率型数据结构,由多个层级的链表组成,每个元素在不同的层中出现的概率是固定的。这种结构使得在平均情况下,插入、删除和查找操作的时间复杂度为 (O(\log n))。

2. 原子操作

ConcurrentSkipListSet 的内部实现依赖于 java.util.concurrent.atomic 包中的原子类,如 AtomicIntegerAtomicReference。这允许在并发环境中安全地更新节点和指针。

3. 锁分段技术

跳表的每个节点都有一个前向指针(即指向下一个节点),在进行插入和删除时,ConcurrentSkipListSet 会使用一种锁分段策略。它对每个节点的更新操作仅锁定该节点及其前后节点,而不是整个数据结构。这种局部性减少了锁竞争,提高了并发性能。

4. CAS(Compare-And-Swap)

ConcurrentSkipListSet 在插入和删除元素时,使用 CAS 操作来更新节点的指针。通过原子性地更新指针,避免了传统锁机制所带来的开销。

5. 遍历操作

在遍历时,ConcurrentSkipListSet 允许其他线程对集合进行并发修改。这是通过复制当前状态的快照(snapshot)来实现的,确保遍历的线程能够看到一致的视图。

1. ConcurrentSkipListMap 与 ConcurrentSkipListSet

JDK中包含两个与SkipList相关的数据结构,分别是ConcurrentSkipListSet和ConcurrentSkipListMap,二者均为并发容器,一个是Set实现一个是Map实现。 而ConcurrentSkipListSet内部实际上包含一个ConcurrentSkipListMap,其将元素作为ConcurrentSkipListMap的key存放,所以本质上也以ConcurrentSkipListMap作为底层实现。这里将主要分析ConcurrentSkipListMap的源代码。

2. 与ConcurrentHashMap对比

  1. ConcurrentSkipListMap与ConcurrentHashMap都是线程安全的并发容器,可以应用于并发读写场景。

  2. ConcurrentHashMap底层基于哈希,ConcurrentSkipListMap底层基于跳表结构,而跳表本身是有序的,所以ConcurrentSkipListMap也是有序的。

3. ConcurrentSkipListMap采用的无锁删除算法

基础的算法基于 HM linked ordered set algorithm (Tim Harris, "A pragmatic implementation of non-blocking linked lists")的变种。它的基本思想是在删除节点时标记待删除结点的下一个结点,来避免并发的插入冲突。作者也提到另一种方案是使用AtomicMarkedReference,但是作者认为AtomicMarkedReference不够高效, 直接使用CAS操作更加高效。

具体在删除时,采用的是类似懒删除的策略,如果一个结点的value为null,则认为它已经被逻辑删除

假设待删除结点为n,b为它的前驱结点,f为它的后继结点

第一步CAS设置n的value为null,此时该结点已经被逻辑删除,插入、查找等操作将会忽略该结点。

第二步CAS设置n的后继结点为一个Marker结点(value指向自己),此时任何操作都不会再其后继续添加结点。

第三步CAS设置n的前驱结点b指向其后继结点f,完成删除。

在这个过程中,如果第一步失败,则会进行重试。第二步或第三步失败也不会影响其他操作,因为该结点value已经被设置成null,其他操作会忽略该结点,相当于该结点已经被删除。并且其他操作内部有帮助删除操作,会检查value已经被设定成null的结点,帮助其完成删除的第二步和第三步。

4. 源码分析

在ConcurrentSkipListMap源代码的基础上,对主要的查询、插入、删除等操作进行分析,并增加了详细的代码注释,帮助理解ConcurrentSkipListMap的源代码。

Set大汇总(横屏观看)

Set有序性线程安全底层实现关键接口特点
HashSetHashMap简单
LinkedHashSetLinkedHashMap插入顺序
TreeSetNavigableMapNavigableSet自然顺序
CopyOnWriteArraySetCopyOnWriteArrayList插入顺序,读写分离
ConcurrentSkipListSetConcurrentSkipListMapNavigableSet自然顺序

从中我们可以发现一些规律:

(1)除了HashSet其它Set都是有序的;

(2)实现了NavigableSet或者SortedSet接口的都是自然顺序的;

(3)使用并发安全的集合实现的Set也是并发安全的;

(4)TreeSet虽然不是全部都是使用的TreeMap实现的,但其实都是跟TreeMap相关的(TreeMap的子Map中组合了TreeMap);

(5)ConcurrentSkipListSet虽然不是全部都是使用的ConcurrentSkipListMap实现的,但其实都是跟ConcurrentSkipListMap相关的(ConcurrentNavigableMap为ConcurrentSkipListMap的具体实现);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值