ConcurrentSkipListMap的跳表按层级组织:最底层含全部有序key-value节点,上层为下层稀疏子集,层数由插入时随机算法动态生成(如50%概率升层),查找从最高层HeadIndex开始,沿right向右、down向下跳跃式定位,最终在底层精确匹配。

跳表的层级怎么组织
ConcurrentSkipListMap 的跳表由多层有序链表构成,最底层(Level 1)包含全部键值对,且严格按 key 排序;上层每一级都是下层的“稀疏子集”,节点数量逐层减少。层级不是固定预设的,而是插入时通过随机算法动态生成——每个新节点有约 50% 概率出现在上一层,25% 出现在再上一层,依此类推。这种概率分布让平均层数趋近于 log₂n,天然避免了树结构中复杂的再平衡操作。
查找时如何“跳”得更快
查找从最高层的头索引(HeadIndex)开始,沿 right 指针向右遍历:只要当前节点的 key 小于目标 key,就继续向右;一旦发现下一个节点的 key ≥ 目标 key,就顺着 down 指针落到下一层,重复该过程。这样每层都大幅缩小搜索范围,最终在底层完成精确比对。
例如查找 key=18:
- 顶层可能只含 [3, 25] → 3
- 中层含 [3, 9, 16, 25] → 在 9 和 16 间定位,再下落
- 底层含全部节点 → 从 16 向右一步即达 18
相比单链表遍历 18 次,跳表仅需约 6–7 步,本质是用空间(多层指针)换时间(跳过无关节点)。
为什么不需要全局锁也能安全查找
所有索引节点(Index)和数据节点(Node)的关键字段均用 volatile 修饰,保证可见性;查找全程只读,不修改任何节点或指针。即使其他线程正在并发插入或删除,查找线程看到的只是某一时刻的快照——可能略旧但结构始终一致(因 CAS 更新遵循原子性和层级约束)。因此无需加锁,天然支持高并发只读访问。
层级设计对性能的实际影响
层级过高会增加内存开销和遍历路径长度;过低则退化为普通链表。ConcurrentSkipListMap 采用 ThreadLocalRandom 生成随机数,并用位运算(如 rnd & 0x80000001 == 0)控制建层概率,使平均层数稳定、方差可控。实测表明,在万级数据下,99% 的查找落在 4–6 层内完成,时间复杂度稳定在 O(log n),波动远小于红黑树的最坏路径。










