Collections.synchronizedList() 返回线程安全的同步包装器,单个操作原子性保障,但复合操作和迭代需手动同步,不保证逻辑一致性,性能介于非同步集合与CopyOnWriteArrayList之间。

Collections.synchronizedList() 是 Java 提供的工具方法,用于将一个普通的、非线程安全的 List(如 ArrayList 或 LinkedList)包装成线程安全的代理对象。它不是创建新集合,而是返回一个同步包装器(synchronized wrapper),所有对它的操作(add、get、remove 等)都会自动加锁,保证单个操作的原子性。
基本用法:包装已有 List
只需把原始 List 传入该静态方法即可:
List
List
此后应只通过 syncList 访问数据,避免直接使用原始 list —— 否则会绕过同步机制,引发线程安全问题。
注意迭代时仍需手动同步
虽然单个方法调用是线程安全的,但**复合操作或遍历过程不自动同步**。例如下面的代码仍是线程不安全的:
立即学习“Java免费学习笔记(深入)”;
for (String s : syncList) { ... } // 可能抛 ConcurrentModificationException
正确做法是显式加锁(使用 syncList 自身作为锁对象):
synchronized (syncList) {
for (String s : syncList) {
// 安全遍历
}
}
不适用于所有并发场景
- 仅保障单个方法调用的线程安全(如
get(i)、size()),不保证多个操作之间的逻辑一致性(比如“检查是否存在再添加”这类if-then-add操作)。 - 性能开销比
CopyOnWriteArrayList小,但比非同步集合大;高竞争下可能成为瓶颈。 - 若需要更高级的并发控制(如批量操作、弱一致性迭代),建议考虑
java.util.concurrent包中的替代品,如CopyOnWriteArrayList或ConcurrentLinkedQueue(注意:没有ConcurrentArrayList)。
常见误用提醒
- 不要把返回的同步列表赋值给
ArrayList类型变量(编译失败)——它返回的是Collections.SynchronizedRandomAccessList这类内部包装类。 - 原始集合若已被其他线程直接访问,同步包装无效;必须确保所有访问都走包装后的引用。
- 不能用于初始化后就不再修改的只读场景——此时应优先用
Collections.unmodifiableList(),更轻量且语义清晰。


















