ConcurrentHashMap 是 Java 高并发线程安全哈希映射,采用分段锁(JDK7)或 CAS+synchronized(JDK8+),key 可为 null(JDK9+ value 不可为 null),支持原子操作如 putIfAbsent、computeIfAbsent 等,遍历为弱一致性,size() 返回近似值,不支持 values().clear() 等批量修改。

ConcurrentHashMap 是 Java 中专为高并发场景设计的线程安全哈希映射,它不依赖全局锁,而是通过分段锁(JDK 7)或 CAS + synchronized 细粒度加锁(JDK 8+)来保证线程安全,性能远优于 Hashtable 或 Collections.synchronizedMap。
直接创建并使用 ConcurrentHashMap
推荐使用无参构造或指定初始容量的方式初始化。ConcurrentHashMap 的 key 和 value 都允许为 null(JDK 9+ 起 value 不允许为 null,但 key 仍可为 null;实际开发中应避免 null 值以防止 NPE)。
- 基本用法:`ConcurrentHashMap
map = new ConcurrentHashMap();` - 插入元素:`map.put("a", 1);` —— 线程安全,无需额外同步
- 获取值:`Integer val = map.get("a");` —— 读操作完全无锁,高效
- 条件更新:`map.putIfAbsent("b", 2);` —— 仅当 key 不存在时插入,原子性保证
常用原子操作替代手动同步
ConcurrentHashMap 提供了多个带语义的原子方法,能避免竞态条件,比先 get 再 put 更可靠。
- `computeIfAbsent(key, mappingFunction)`:key 不存在时才调用函数生成值并放入,适合缓存场景
- `computeIfPresent(key, remappingFunction)`:key 存在且非 null 时更新 value
- `merge(key, value, remappingFunction)`:存在则合并,不存在则插入,例如计数累加:
map.merge("count", 1, Integer::sum) - `replace(key, oldValue, newValue)`:仅当当前值等于 oldValue 时替换,类似乐观锁
遍历时的安全注意事项
ConcurrentHashMap 的迭代器是弱一致性(weakly consistent),不会抛出 ConcurrentModificationException,但可能反映某次操作的“快照”,不保证实时性。
立即学习“Java免费学习笔记(深入)”;
- 遍历推荐用 forEach、reduce、search 等内置方法,它们内部自动处理并发:`map.forEach((k, v) -> System.out.println(k + "=" + v));`
- 避免在 for-each 循环中调用 remove/put —— 虽然不报错,但行为不可预测;应改用 `remove(key)` 或 `compute()` 系列方法
- 如需强一致性视图,可考虑先 `new HashMap(map)` 快照复制,再遍历副本(注意内存和时效权衡)
与普通 HashMap 的关键区别
不是简单加锁版 HashMap,设计目标和行为有本质差异:
- size() 返回近似值(JDK 8+),高并发下不保证精确;如需准确计数,可用 mappingCount()
- 不支持基于 Collection 视图的批量结构修改(如 values().clear() 会抛 UnsupportedOperationException)
- keySet()/values()/entrySet() 返回的集合是“实时”视图,但其 iterator 不阻塞写操作
- 不允许在 compute 方法中修改 map 自身(会导致 IllegalThreadStateException),避免死锁


















