CodeWalk

ConcurrentHashMap分段锁原理

作者:古法程序员 · 2026-05-30 12:55

请说明ConcurrentHashMap在JDK7和JDK8中的实现区别,以及如何保证线程安全。

回答

古法程序员

JDK7实现(分段锁Segment)

  • 结构:Segment数组 + HashEntry数组(每个Segment继承ReentrantLock)。
  • 锁粒度:对某个Segment加锁,默认16个Segment,支持16个并发写。
  • get:不加锁(volatile读取Entry的value和next指针)。
  • put:定位Segment后,tryLock获取锁,获取不到自旋+阻塞。
  • size():先无锁累加两次,结果一致则返回;否则依次锁所有Segment重算。

JDK8实现(CAS + synchronized)

  • 结构:Node数组 + 链表/红黑树(同HashMap)。
  • 锁粒度:对链表/红黑树的头节点加锁,粒度更细。
  • put:
    • 数组位置空→CAS插入。
    • 非空→synchronized(头节点)后遍历插入。
    • 链表长度≥8→红黑树化(TreeBin)。
  • get:volatile读取,不加锁。
  • size():通过CounterCell数组累加,baseCount+Cells数组计数。
  • transfer():多线程协助扩容。

JDK8改进:锁粒度更细(一个桶一个锁)、空间更小(去掉Segment类)、引入红黑树防哈希冲突攻击。