collections.synchronizedsortedmap 的核心作用是将普通 sortedmap(如 treemap)包装为线程安全视图,仅对单个操作加同步锁,不保证复合操作或遍历的原子性;适用于读多写少场景,但遍历时必须手动以原包装对象为锁同步。

Collections.synchronizedSortedMap 的核心作用,是把一个已有的 SortedMap(比如 TreeMap)包装成线程安全的视图——它不改变原 map,只是加了一层同步保护,让单个操作(如 put、get、remove)自动串行化执行。
它解决什么问题
普通 SortedMap(如 TreeMap)本身不是线程安全的。多个线程同时读写时,可能引发数据错乱、ConcurrentModificationException,甚至内部结构损坏。synchronizedSortedMap 提供一种轻量级方案,在不换用 ConcurrentSkipListMap 的前提下,快速获得基本线程安全性。
- 适用于读多写少、并发压力不高的场景
- 适合已有代码中临时增强安全性,改动成本低
- 不适用于高频迭代+修改混合操作的复杂并发逻辑
关键使用规则
它只保证“方法调用”层面的同步,不保证复合操作或遍历过程的原子性。违反规则极易导致不可预测行为。
- 所有单点操作(
put、get、containsKey)可直接调用,无需额外同步 - 获取视图(如
keySet()、entrySet()、subMap())后,对这些视图的遍历必须手动加锁,且锁对象必须是原始 synchronized map 实例 - 不能对子视图(如
subMap或tailMap)本身加锁,否则同步失效 - 迭代器操作(
iterator().hasNext()/next())全程需包裹在synchronized(map)块内
典型错误写法
常见误区集中在“以为包装后就万事大吉”,尤其在遍历时忽略同步范围。
- 直接用
for (Object o : map.keySet())—— 这会隐式创建 iterator,但没加锁,线程不安全 - 对
keySet()对象加锁:synchronized(keySet) { ... }—— 锁错对象,无效 - 在遍历中调用
map.remove()或其他修改操作 —— 即使加了锁,也可能破坏遍历一致性 - 混用原始
TreeMap和包装后的 map —— 原始 map 仍可被直接修改,绕过同步
替代方案对比
当需求超出 synchronizedSortedMap 能力范围时,应考虑更合适的并发集合:
- 需要高并发读写 + 排序能力 → 用
ConcurrentSkipListMap(真正无锁、支持并发遍历) - 仅需不可变排序视图 →
Collections.unmodifiableSortedMap() - 若排序非必需,仅需线程安全 map →
ConcurrentHashMap性能通常更好 - 涉及频繁复合操作(如“存在则更新”)→ 使用
ConcurrentSkipListMap的computeIfAbsent等原子方法
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











