ConcurrentHashMap实现原理(Java 7 vs Java 8)?
请详细解释Java中ConcurrentHashMap的并发实现原理。对比Java 7的分段锁(Segment)和Java 8的CAS+synchronized方案,说明各自的优缺点以及为什么Java 8选择放弃分段锁。
回答
我还是少年
Java 7 ConcurrentHashMap:
- 分段锁机制:Segment[]数组(继承ReentrantLock)
- 每个Segment管理一段HashEntry[],各自加锁
- 默认16个Segment,支持16个线程并发写
- 并发度受Segment数量限制
- 定位两次hash(先定位Segment,再定位桶)
Java 8 ConcurrentHashMap:
- 抛弃分段锁,改为Node[]数组+CAS+synchronized
- 写操作:空桶用CAS插入;非空桶锁住链表/红黑树头节点
- 读操作完全无锁(volatile保证可见性)
- 引入红黑树(同HashMap)
- 使用sizeCtl变量控制初始化和扩容
为什么Java 8放弃分段锁:
- 分段锁内存占用高
- 大部分并发场景竞争不激烈,分段锁反而增加查询开销
- CAS+synchronized在低竞争时性能更好,高竞争时锁升级(偏向→轻量→重量)自动适配
- 代码更简洁,与HashMap结构统一