ConcurrentHashMap采用链地址法处理哈希冲突,JDK 8+中结合CAS+synchronized实现细粒度锁,链表长度≥8且数组长度≥64时树化为红黑树,≤6时退化回链表,并通过扰动哈希、位运算索引、协作扩容与volatile读优化保障高并发性能。

ConcurrentHashMap 处理哈希冲突的核心思路和 HashMap 一致,仍采用链地址法(拉链法),但在此基础上叠加了线程安全设计与结构优化,从而在高并发下既避免冲突恶化,又保障性能不崩。
链表 + 红黑树双结构应对冲突
和 JDK 1.8+ 的 HashMap 一样,ConcurrentHashMap 的每个桶(数组位置)也支持两种形态:
- 冲突较少时:用单向链表串连同桶的 Node 节点,插入尾部,查找按顺序遍历;
- 冲突严重时(链表长度 ≥ 8 且 table.length ≥ 64):自动转为红黑树,将查找时间从 O(n) 优化至 O(log n);
- 树中节点数 ≤ 6 时,会退化回链表,减少小规模数据下的树维护开销。
这个树化阈值不是硬编码死的,而是由实际桶内节点数、当前数组容量共同决定,防止过早树化浪费空间。
扰动哈希 + 位运算降低冲突概率
哈希冲突越少,链表/红黑树越短,性能越稳。ConcurrentHashMap 使用和 HashMap 几乎相同的扰动函数:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
立即学习“Java免费学习笔记(深入)”;
hash = (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16)再通过 (n - 1) & hash 计算桶索引(n 是 table 长度,始终为 2 的幂)。这种设计让 hashCode 的高位也参与索引计算,显著改善低位重复导致的聚集现象,尤其对 String、Integer 等常用 Key 更友好。
分段控制 + 协作扩容缓解冲突恶化
哈希冲突本身无法完全避免,但 ConcurrentHashMap 重点防范“冲突引发连锁性能劣化”。关键机制包括:
- 细粒度锁(JDK 1.7)或 CAS + synchronized(JDK 1.8+):写操作只锁定具体桶或其所在链表头,不阻塞其他桶,避免因一个热点桶拖垮全局;
- 多线程协作扩容:当总元素数超阈值(capacity × loadFactor,默认 0.75),扩容不是单线程搬数据,而是多个线程通过 transferIndex 分片搬运,旧表仍可读、部分桶可写,大幅缩短扩容窗口;
- ForwardingNode 标记迁移中桶:访问到正在迁移的桶时,线程会主动协助搬运,避免查询卡在无效链表上。
读操作无锁 + volatile 保证可见性
get 操作全程不加锁,直接通过 hash 定位桶,遍历链表或红黑树。Node 的 next 和 value 字段均用 volatile 修饰,确保其他线程写入后能被立即看到。即使在扩容中遇到 ForwardingNode,也能无缝跳转到新表继续查找——这使得高并发读场景下,冲突桶的存在几乎不影响吞吐量。


















