ConcurrentSkipListSet是线程安全、有序、去重的集合,基于ConcurrentSkipListMap实现,支持高并发读写和自然排序;适用于需排序与并发的场景,优于CopyOnWriteArraySet和synchronized Set。

ConcurrentSkipListSet 是 Java 并发包中线程安全、有序、去重的集合实现,底层基于 ConcurrentSkipListMap,天然支持高并发读写与自然排序(要求元素可比较),适合替代非线程安全的 TreeSet。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
为什么选 ConcurrentSkipListSet 而不是 CopyOnWriteArraySet 或 synchronized Set?
• CopyOnWriteArraySet 写操作开销大(每次修改都复制整个数组),不适合频繁增删场景;
• Collections.synchronizedSet(new TreeSet()) 虽有序且线程安全,但所有操作串行化,吞吐量低;
• ConcurrentSkipListSet 采用跳表结构,支持细粒度锁 + 无锁读,读写并发度高,且保持 O(log n) 平均时间复杂度和自然排序。
使用前提:元素必须可比较
• 元素类需实现 Comparable 接口(如 String、Integer 等已内置);
• 或创建时传入自定义 Comparator:new ConcurrentSkipListSet(Comparator.comparing(User::getId));
• 若元素不可比且未提供比较器,运行时抛 ClassCastException。
典型高并发去重 + 有序访问示例
假设多个线程持续上报订单 ID(Long 类型),需实时去重并按 ID 升序获取最新前 100 条:
• 创建集合:ConcurrentSkipListSet<long> uniqueOrderIds = new ConcurrentSkipListSet();</long>
• 多线程插入(自动去重):uniqueOrderIds.add(orderId); // 线程安全,重复添加无副作用
• 安全遍历前 N 个(注意:迭代器弱一致性,不抛 ConcurrentModificationException):uniqueOrderIds.stream().limit(100).collect(Collectors.toList());
• 获取子集(如 ID ≥ 1000 的最小 50 个):uniqueOrderIds.tailSet(1000L).stream().limit(50).toList();
注意事项与优化点
• add/remove/contains 均为线程安全,无需额外同步;
• 迭代过程不阻塞写入,但看到的可能是“某一时刻的快照”,不保证强实时性;
• 不支持 null 元素(否则抛 NullPointerException);
• 若仅需去重不要求排序,ConcurrentHashMap(key 去重)+ keySet() 性能更高;
• 高频小范围查询(如 top-K)可结合 subSet/headSet/tailSet 减少遍历开销。

















