JDK7中ConcurrentHashMap采用分段锁设计,以Segment数组实现变量隔离:每个Segment继承ReentrantLock并维护独立HashEntry数组,通过两级哈希定位到唯一Segment及桶位,写操作锁定目标Segment,读操作依赖volatile和final字段无锁执行,锁粒度降至1/16,显著提升并发性能。

ConcurrentHashMap 在 Java 7 中的分段锁设计,核心在于用 Segment 数组 实现变量隔离——不是靠单个全局锁,而是把整个哈希表逻辑切分为多个独立“小地图”,每个 Segment 管理自己的一片 HashEntry 区域,彼此互不干扰。
Segment 是什么:带锁的子哈希表
Segment 类继承自 ReentrantLock,本身就是一个可重入锁;同时它内部维护一个 HashEntry[] table,结构上等同于一个简化版 HashMap(数组 + 单向链表)。这意味着:
- 每个 Segment 拥有独立的锁、独立的容量、独立的扩容逻辑;
- 不同线程操作不同 Segment 的 key,完全不会触发锁竞争;
- 默认初始化 16 个 Segment(对应并发度 concurrencyLevel=16),可通过构造参数调整,但创建后不可变。
变量隔离怎么实现:定位 + 锁定 + 局部操作
隔离的关键不在“物理分割”,而在“访问路径隔离”:每次操作都通过两级哈希计算,精准落到唯一 Segment 和其内部唯一桶位。
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 第一级:用 key 的 hash 值高几位(通过
segmentShift和segmentMask)快速定位到某个 Segment 下标; - 第二级:在该 Segment 内部,再用 hash 值低几位定位到
HashEntry[]中的具体索引; - 只有执行写操作(如 put/remove)时才对目标 Segment 加锁;读操作(get)甚至不需要加锁,依赖
volatile修饰的next引用和final字段保证可见性与安全性。
为什么能提升并发性能:锁粒度从“全表”降到“1/16”
对比 Hashtable 的全局 synchronized,Segment 架构把锁竞争面大幅收窄:
立即学习“Java免费学习笔记(深入)”;
- 16 个 Segment → 理论上最多支持 16 个线程同时写入不同段;
- 读操作几乎无阻塞,因为不依赖锁,只靠 volatile 语义读取链表节点;
- 即使某段发生哈希冲突形成长链,也只影响该 Segment 内部性能,不影响其他段的响应速度。
隔离的代价:内存与扩展性限制
变量隔离不是免费的,它带来三类显性成本:
- 每个 Segment 都要维护自己的 table 数组、计数器、扩容阈值等元数据,内存开销明显高于普通 HashMap;
- 扩容只能按 Segment 逐个进行,无法整体 rehash,导致扩容过程更慢、更复杂;
- 并发度被初始 Segment 数量锁定,运行时无法动态增加 Segment,容易成为高并发场景下的瓶颈。

















