ConcurrentSkipListSet 是基于跳表实现的线程安全有序集合,底层依赖 ConcurrentSkipListMap,支持 O(log n) 增删查、无锁高并发、弱一致性迭代,不支持 null,适用于需排序与并发兼顾的场景。

ConcurrentSkipListSet 是 Java 并发包(java.util.concurrent)中提供的线程安全、有序、基于跳表(Skip List)实现的集合类,它底层依赖 ConcurrentSkipListMap,天然支持高并发下的插入、删除、查找操作,且保持元素自然排序(或按指定 Comparator 排序)。
为什么选 ConcurrentSkipListSet 而不是 TreeSet + synchronized?
TreeSet 本身不是线程安全的,加 synchronized 会严重串行化,吞吐量低;而 ConcurrentSkipListSet 使用无锁(Lock-Free)+ CAS 的跳表结构,在多线程场景下性能更优、扩展性更好,同时支持 O(log n) 平均时间复杂度的增删查操作,并保证遍历过程中不会抛出 ConcurrentModificationException。
基本用法:创建与添加元素
直接 new 即可,支持自然排序(要求元素实现 Comparable)或传入自定义 Comparator:
- 默认自然排序(如 Integer、String 等已实现 Comparable):
Set<Integer> set = new ConcurrentSkipListSet<>(); - 自定义排序(例如按字符串长度降序):
Set<String> set = new ConcurrentSkipListSet<>(Comparator.comparing(String::length).reversed()); - 添加元素是线程安全的,无需额外同步:
set.add(10); set.add(3); set.add(7); // 结果为 [3, 7, 10]
常用并发安全操作示例
它支持很多原子性方法,适合在高并发逻辑中直接使用:
立即学习“Java免费学习笔记(深入)”;
- addIfAbsent(e):仅当元素不存在时才添加,返回是否成功(避免重复插入)
- remove(Object o):线程安全删除,返回是否删除成功
- contains(Object o):安全判断是否存在
- ceiling(E e)、floor(E e)、higher(E e)、lower(E e):获取邻近有序元素(如“大于等于 e 的最小值”),适合范围查询场景
- subSet(from, to)、headSet(to)、tailSet(from):返回视图(同样线程安全),注意这些子集也支持并发修改
注意事项与限制
虽然强大,但需注意几点实际约束:
- 不支持 null 元素(add(null) 会抛 NullPointerException)
- 迭代器弱一致性:遍历时可能看到部分更新结果,但不会抛异常,也不保证反映某一时刻的快照
- 不能用于强一致性要求的场景(如必须精确反映“某次 add 后立刻被所有线程看到”),此时需配合其他同步机制
- 相比 HashSet 或 CopyOnWriteArraySet,内存占用略高(跳表多层指针开销),但换来了并发与排序能力的平衡


















