concurrenthashmap天生线程安全,无需额外加锁,支持原子复合操作如putifabsent、computeifabsent和merge,遍历具弱一致性,性能依赖合理初始化与避免lambda中耗时操作。

直接用 ConcurrentHashMap 就行,它天生线程安全,不用加锁、不需包装,所有基础操作(put、get、remove)都已内置并发控制。
创建与基础操作
初始化简单,支持泛型和可选初始容量:
ConcurrentHashMap<string integer> map = new ConcurrentHashMap();</string>- 若预估数据量较大,可指定初始容量避免频繁扩容:
new ConcurrentHashMap(64) -
map.put("a", 1);和map.get("a")可被任意线程并发调用,无风险
避免竞态条件:用原子复合方法
别写“先查再改”这种非原子逻辑,比如 if (!map.containsKey(k)) map.put(k, v) —— 多线程下可能重复插入。应替换为:
-
map.putIfAbsent(k, v):键不存在才设值 -
map.computeIfAbsent(k, key -> expensiveLoad()):适合缓存场景,函数只执行一次 -
map.merge(k, v, (old, newV) -> old + newV):存在则合并,不存在则设初值
遍历时注意弱一致性
它的迭代器不抛 ConcurrentModificationException,但也不保证看到最新修改:
- 适合监控、日志、统计等对实时性要求不高的场景
- 推荐用
map.forEach((k, v) -> {...})或map.entrySet().forEach(...) - 避免在遍历中依赖严格顺序或强一致性结果
性能关键点
高效不是默认的,需要合理使用:
- 避免在
compute或merge的 lambda 中做耗时操作(如 I/O、网络请求),会阻塞该桶的其他写入 - 高并发写入时,初始容量和负载因子影响分段效果,建议按预期并发线程数 × 平均每线程写入量预估
- 读多写少场景下,几乎零开销;写冲突集中在同一桶时,
synchronized锁单个链表头仍比全局锁高效得多
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











