优先选 ConcurrentHashMap,因其采用 CAS + synchronized 细粒度加锁,读操作基本无锁、写操作仅锁单个桶,并支持原子方法;读多写少可考虑 ReadWriteLock + HashMap;内容不变时用 Map.of() 等不可变 Map;避免使用 Hashtable。

选线程安全的 Map 类,关键看你的并发场景:读多还是写多、是否只读、对性能要求高不高。不是“哪个更安全”,而是“哪个更合适”。
高并发读写,优先用 ConcurrentHashMap
这是现代 Java 应用的默认选择。JDK 8 后它不再用分段锁,改用 CAS + synchronized 细粒度加锁,读操作基本无锁,写操作只锁单个桶(Node)。支持原子方法如 putIfAbsent、computeIfAbsent,避免了手动同步的竞态问题。
适用情况:
- 缓存系统(如用户会话、配置项)
- 计数器、统计类场景(如接口调用量聚合)
- 多个线程频繁 put/get/remove 的通用共享 Map
简单同步、线程少,可用 Collections.synchronizedMap
它把任意 Map(比如 new HashMap())包装成同步版本,所有 public 方法都加了 synchronized。好处是代码改动小,一行就能包住;坏处是全局锁,同一时间只能一个线程执行任何操作,吞吐量低。
立即学习“Java免费学习笔记(深入)”;
注意两点:
- 复合操作仍需手动加锁,比如“先检查再插入”必须写成 synchronized(map) { if (!map.containsKey(k)) map.put(k, v); }
- 迭代时要显式同步,否则可能抛 ConcurrentModificationException
读远多于写,考虑 ReadWriteLock + HashMap
读锁可共享,写锁独占。在读操作占比超 90%、写极少的场景下,性能可能优于 synchronizedMap。但你要自己管理锁的获取与释放,容易漏掉 finally 解锁,也容易误用(比如读锁里调了写操作)。
不推荐新手直接用,除非你明确压测过且 synchronizedMap 成了瓶颈。
内容固定不变,直接用不可变 Map
如果 Map 构建后就再也不改(比如加载配置、枚举映射表),用 Map.of()(JDK 9+)、Map.copyOf()(JDK 10+)或 Guava 的 ImmutableMap。它们线程安全、内存紧凑、不可篡改,且无同步开销。
例子:
- Map
config = Map.of("timeout", 3000, "retries", 3); - 构造后任何修改都会抛 UnsupportedOperationException
别再用 Hashtable —— 它是历史遗留,方法级全局锁,不支持 null,没红黑树优化,性能差,官方文档已标记为 legacy。


















