ConcurrentSkipListMap 是 Java 并发包中基于跳表实现的线程安全、有序映射,支持 CAS/volatile 无锁并发、自然或自定义排序、高效范围查询与弱一致性迭代,不允 null 键值。

ConcurrentSkipListMap 是 Java 并发包(java.util.concurrent)中提供的线程安全、可排序的映射实现,底层基于跳表(Skip List)结构,支持高并发读写,同时保持键的自然顺序或自定义比较器顺序。它不使用锁(如 ReentrantLock),而是通过 CAS 和 volatile 实现无锁并发控制,适合读多写少、又需有序遍历的场景。
一、基本用法与初始化
创建一个 ConcurrentSkipListMap 时,可指定自然排序(要求 key 实现 Comparable)或传入 Comparator:
- 自然排序(key 为
Integer、String等):
ConcurrentSkipListMap<Integer, String> map = new ConcurrentSkipListMap<>();
- 自定义排序(例如按字符串长度降序):
ConcurrentSkipListMap<String, Integer> map = new ConcurrentSkipListMap<>((a, b) -> b.length() - a.length());
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
二、关键并发操作与线程安全性
所有 public 方法(如 put、get、remove、containsKey)都是线程安全的,无需额外同步。特别注意以下行为:
-
putIfAbsent(k, v):仅当 key 不存在时插入,原子性保证,适合“首次注册”逻辑 -
computeIfAbsent(k, mappingFunction):若 key 不存在,则用函数计算 value 并插入;函数在写入前调用,但不保证只执行一次(因可能重试),函数应无副作用 -
subMap(from, to)、headMap(to)、tailMap(from):返回的子映射也是并发安全且实时反映原映射变化的视图
三、有序遍历与范围查询
得益于跳表结构,它支持高效(平均 O(log n))的有序迭代和范围操作:
- 正向遍历(升序):
for (Map.Entry<Integer, String> e : map.entrySet()) { ... }
- 反向遍历(降序):
for (Map.Entry<Integer, String> e : map.descendingMap().entrySet()) { ... }
- 获取 [10, 20) 区间内所有条目:
Map<Integer, String> range = map.subMap(10, true, 20, false); // 包含 10,不包含 20
四、使用注意事项
- null key 或 value 均不允许,否则抛
NullPointerException - 不支持
Collection视图的批量结构修改(如entrySet().clear()是线程安全的,但entrySet().removeAll(...)不推荐,应改用循环 +remove) - 迭代器是弱一致性(weakly consistent):不抛
ConcurrentModificationException,可反映部分更新,但不保证看到所有已发生的修改 - 相比
TreeMap,它牺牲了部分内存效率(跳表需额外指针),换来了更好的并发伸缩性;相比ConcurrentHashMap,它多了排序能力,但写性能略低

















