concurrentskiplistmap 基于无锁跳表结构与 cas 实现线程安全,通过多层有序链表和 volatile 字段保障可见性与原子性,支持高并发读写及天然有序操作。

ConcurrentSkipListMap 并不是靠锁来实现线程安全,而是基于无锁(lock-free)的跳表(Skip List)结构 + CAS(Compare-And-Swap)操作,同时保证有序性和高并发读写性能。
跳表结构本身支持高效并发插入/删除
跳表是一种概率性数据结构,通过多层链表实现接近 O(log n) 的平均查找、插入、删除复杂度。每一层是下一层的“快速索引”,最底层包含全部元素并有序排列。
- 每个节点包含一个 key-value 对和多个指向同层后继节点的指针(层数随机生成,通常服从几何分布)
- 插入时,先从顶层开始逐层向下定位插入位置,再用 CAS 原子地更新各层的后继指针
- 删除时,先逻辑标记节点为“已删除”(通过将 value 设为 null 或使用标记位),再物理移除——避免其他线程正在遍历时出现不一致
所有操作都基于 volatile + CAS,不依赖 synchronized
ConcurrentSkipListMap 中的关键字段(如节点的 next 指针、value 字段)都被声明为 volatile,确保可见性;所有修改都通过 Unsafe 类的 CAS 方法完成。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 例如 put() 会调用 doPut():先找到插入位置,构造新节点,再对每一层的前驱节点执行 casNext() 尝试更新指针
- 如果 CAS 失败(说明其他线程已修改),就重试或回退——这是典型的乐观并发策略
- 没有全局锁或分段锁,读操作完全无锁,写操作只影响局部链表段,冲突概率低
天然有序,无需额外排序开销
跳表的底层链表始终按 key 排序维护,所有操作(get/put/remove/ceilingKey/floorEntry 等)都基于有序遍历,不需要像 HashMap 那样额外排序或重建结构。
- 迭代器也是弱一致性(weakly consistent):可反映某时刻的快照,允许遍历时有其他线程修改,但不会抛出 ConcurrentModificationException
- 支持 NavigableMap 接口的所有有序操作,比如 subMap、headMap、tailMap,内部通过定位边界节点+截断链表实现,同样基于 CAS 和 volatile 保障并发安全
实际使用中要注意的点
虽然线程安全,但某些组合操作仍需外部同步,比如“检查是否存在再插入”这类非原子逻辑。
- 推荐用 putIfAbsent()、computeIfAbsent() 等内置原子方法替代手动判断 + put
- key 必须实现 Comparable 或传入 Comparator,否则运行时报 ClassCastException(跳表依赖比较结果确定位置)
- 内存占用略高于 TreeMap(因多层指针),但并发性能优势明显,尤其在读多写少场景下
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










