ConcurrentHashMap 如何保证线程安全?

发布于

一、JDK 1.7:分段锁

内部是 Segment 数组,每个 Segment 是一个小 HashMap,put 时只锁当前 Segment,并发度 = Segment 数(默认 16)。

二、JDK 1.8:CAS + synchronized

  • 数组节点为空时,用 CAS 插入,无锁。
  • 节点不为空时,synchronized 锁当前桶头节点。
  • 扩容时多线程协作迁移数据。

三、与 Hashtable 对比

ConcurrentHashMap Hashtable
锁粒度 桶级 整个表
性能 高 低
null 键/值 不允许 不允许

四、为什么不允许 null

因为 get 返回 null 时无法区分是"key 不存在"还是"value 就是 null",并发场景下会产生歧义。