collections.synchronizedmap适用于读多写少、操作粒度粗的场景,如静态配置缓存;需手动同步复合操作;适合与synchronizedlist等统一风格使用;不适用于高并发写或频繁迭代场景。

Collections.synchronizedMap 是 Java 提供的一种轻量级线程安全包装方式,它通过在每个 public 方法上加 synchronized(锁住整个 map 对象)来保证操作的原子性。但它不是万能解药,用对场景才能真正发挥价值。
适合读多写少、操作粒度粗的场景
当你的 Map 主要用于缓存配置、静态字典、运行时只初始化一次且后续几乎只读取(比如国家代码映射表、HTTP 状态码说明),而写入仅发生在应用启动阶段,这时 synchronizedMap 足够高效又简单。
- 读操作(
get)被同步,但实际竞争极小,性能损耗可忽略 - 写操作(
put)虽锁全表,但因极少发生,不影响整体吞吐 - 相比
ConcurrentHashMap,代码更直观,无需处理分段锁或 computeIfAbsent 的语义细节
需要手动同步复合操作的场景
如果业务逻辑涉及“检查后执行”(check-then-act),例如先判断 key 是否存在再 put,synchronizedMap 本身不提供原子性保障——必须显式加锁:
- 错误写法:
if (!map.containsKey(k)) map.put(k, v);→ 两个方法各自同步,中间可能被其他线程插入 - 正确做法:用
synchronized (map) { if (!map.containsKey(k)) map.put(k, v); } - 本质是把多个调用包裹进同一把锁,弥补了 synchronizedMap 的“方法级同步”局限
与 Collections.synchronizedList 类比使用,保持风格统一
在遗留系统或团队约定中,若已广泛使用 Collections.synchronizedList 或 synchronizedSet,为降低认知成本和维护复杂度,对 Map 也选用 synchronizedMap 是合理选择。
- 所有集合都走同一套同步模型,调试和排查问题路径一致
- 避免混用
ConcurrentHashMap和synchronizedMap导致的锁行为差异(如迭代器是否强一致性) - 特别适用于单元测试中快速构造线程安全的测试数据容器
不适合高并发写、细粒度操作或迭代频繁的场景
一旦出现高频 put/remove、遍历中修改、或要求弱一致性迭代器(如允许边遍历边更新),synchronizedMap 就会成为瓶颈:
- 每次
get都锁整个 map,写多时读也被阻塞 - 迭代器返回的是“失败快速”(fail-fast)版本,遍历时其他线程修改会抛
ConcurrentModificationException - 没有
computeIfAbsent这类原子操作支持,需自行同步封装
此时应优先考虑 ConcurrentHashMap,或根据具体需求评估是否需要更细粒度的锁控制。










