ConcurrentHashMap 如何保证线程安全?
Java 集合面试题发布于
一、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",并发场景下会产生歧义。