concurrentskiplistmap 是线程安全但弱一致的有序 map,基于跳表实现,支持无锁并发操作;迭代非实时快照,size() 为近似值,submap 等视图 clear() 会清空整个原 map。

ConcurrentSkipListMap 是线程安全的,但不是强一致的有序 Map
它用跳表(skip list)代替红黑树实现排序,所有操作(put、get、remove、subMap)都无锁并发执行,靠 CAS 和 volatile 保证可见性。但它不提供类似 ConcurrentHashMap 的“弱一致性迭代器”——迭代时可能看到部分更新,也可能跳过刚插入的元素,不能当作实时快照用。
常见错误现象:ConcurrentModificationException 不会抛(因为没用 modCount),但遍历中另一线程插入/删除,结果可能漏项或重复;size() 返回的是近似值,高并发下可能偏差很大。
- 如果需要强顺序+强一致性,别用它,改用
TreeMap+ 外层synchronized(吞吐低但语义明确) -
headMap(k)、tailMap(k)返回的子视图是实时联动的,修改子视图等于修改原 Map - 构造时传入自定义
Comparator必须满足“可比性”:对任意 a、b,compare(a,b)和compare(b,a)符号必须相反,否则跳表结构会损坏
为什么不用红黑树而选跳表?性能和实现权衡在哪
红黑树在并发场景下平衡操作(旋转、染色)需要锁或复杂 CAS 链,而跳表天然支持局部修改:插入一个节点只影响 O(log n) 层的相邻指针,每层可独立 CAS 更新,冲突概率低。实测在写多读少场景下,ConcurrentSkipListMap 的 put 吞吐通常是 ConcurrentHashMap + 排序包装的 2–3 倍。
但代价明显:memory footprint 更大(每个节点平均存 2–4 个指针,而非红黑树的 3 个),且 ceilingKey、floorKey 这类范围查找虽是 O(log n),常数因子比 TreeMap 高约 30%。
- JDK 8+ 默认最大层数是 32,可通过 JVM 参数
-XX:MaxSkipListLevel调整(极少需要) - 初始化时指定
Comparator.naturalOrder()比传null略快,因为避免运行时反射检查 - 不支持
null键或值,插入null直接抛NullPointerException,这点和TreeMap一致
subMap / headMap / tailMap 返回的视图,修改行为容易误判
这些方法返回的是“实时视图”,不是拷贝。对视图的 put、remove 会直接作用于底层跳表,但 clear() 会清空整个原始 Map(不是仅清子范围)——这是最容易踩的坑。
示例:map.subMap(10, true, 20, false) 返回 [10,20),调用其 clear() 会删掉原始 Map 中所有键 ≥10 且 不会影响其他范围,但如果你以为它只清子集,就错了。
- 视图本身不支持
putIfAbsent或computeIfPresent等衍生方法,调用会抛UnsupportedOperationException - 视图的
keySet()、values()也是实时视图,同样不可clear(),但可以remove()单个元素 - 如果原始 Map 已被 GC,视图仍持有弱引用,但访问时会触发
IllegalStateException
与 TreeMap / ConcurrentHashMap + 排序对比时的关键取舍点
它不是“并发版 TreeMap”,而是“有序 + 并发”两个需求折中的产物。如果你的应用里排序只是偶尔用于分页查询(如管理员后台查最近 100 条日志),但写入频繁,ConcurrentSkipListMap 合适;如果排序是核心逻辑(比如实时计算排名、滑动窗口聚合),且要求严格单调,它反而会因弱一致性引入隐晦 bug。
-
TreeMap+synchronized:适合读多写少、一致性优先的场景,单线程性能略优,但锁粒度是全表 -
ConcurrentHashMap+ 外部维护TreeSet<k></k>:能解耦读写,但需手动保证键集合与 Map 数据一致,易出错 -
ConcurrentSkipListMap的keySet().stream().sorted()没意义——它本来就是有序的,流式再排是冗余开销
最常被忽略的一点:它的 containsKey 和 get 虽然快,但底层仍要走 log(n) 层指针跳转,比 ConcurrentHashMap 的哈希一次定位慢不少。别因为它“Map”名字就默认它适合高频随机查——先想清楚你到底要“有序”还是“快查”。










