C# 中没有内置 ConcurrentSkipList,因 .NET 官方未实现线程安全且有序的高并发跳表结构;替代方案为使用第三方库(如 ConcurrentCollections)或手动加锁封装 SortedSet。

ConcurrentSkipList 在 C# 中 **不是内置类型**,.NET 标准库(包括 .NET 5/6/7/8/9)至今(2025年12月)**没有提供 ConcurrentSkipListMap 或 ConcurrentSkipListSet 的等价实现**。
为什么 C# 没有内置 ConcurrentSkipList?
Java 的 ConcurrentSkipListMap/Set 是 J.U.C 包为高并发有序场景量身定制的无锁跳表结构,而 .NET 的并发集合设计路径不同:
- .NET 优先强化了
ConcurrentDictionary(哈希分段锁)和ConcurrentQueue等无序/队列类,但对「线程安全 + 有序 + 高并发」这一组合,官方未落地跳表实现 -
SortedSet和SortedList是有序的,但**完全不支持并发修改**——多线程写入会直接抛InvalidOperationException或产生未定义行为 - 虽然 .NET 6+ 引入了
System.Collections.Generic.PriorityQueue,但它不支持范围查询、导航操作(如ceiling、floor),也不满足「并发 + 排序 + Navigable」需求
C# 中替代 ConcurrentSkipListSet 的实际方案
若你正需要类似 Java 中 ConcurrentSkipListSet 的能力(即:线程安全、自动排序、支持子集/前驱/后继查询),目前只有两条可行路径:
-
用
ConcurrentDictionary+ 外部锁 +SortedSet包装:手动加lock或ReaderWriterLockSlim,牺牲并发度换正确性;适用于读多写少、QPS 不高的场景 -
引入第三方库:例如
ConcurrentCollections(开源 NuGet 包),它提供了ConcurrentCollections和ConcurrentSkipListSet,底层基于跳表 + CAS,API 风格贴近 Java,已在生产环境验证
示例(使用第三方库):
var set = new ConcurrentSkipListSet(); set.Add(42); set.Add(15); set.Add(99); // O(log n) 并发安全的导航操作 int? ceiling = set.Ceiling(50); // → 99 int? floor = set.Floor(50); // → 42
误用 SortedSet 做并发读写的典型错误
很多开发者尝试直接把 ConcurrentSkipListMap 放进多线程环境,结果出现诡异行为:
- 现象:遍历时抛
SortedSet,或返回重复/丢失元素 - 原因:
InvalidOperationException: Collection was modified内部是红黑树,所有结构变更(SortedSet/Add)都会重平衡,且无任何同步机制 - 注意:
Remove不是快照式迭代器 —— 它在遍历中遇到并发修改会立即失败,不像 Java 的GetEnumerator()那样提供弱一致性遍历
跳表的局部更新特性决定了它天然适合高并发有序场景,而 C# 官方尚未填补这个空白。如果你的业务强依赖 ConcurrentSkipListSet、subSet、headSet 或低延迟范围扫描,别硬套 tailSet + 排序临时列表 —— 那会退化成 O(n log n),且无法保证原子性。要么接受第三方库,要么自己基于 ConcurrentDictionary 和链表手撸跳表(不推荐)。










