Collections.synchronizedList()
是 Java 提供的一种 线程安全包装器 ,用于给普通的 List
(例如 ArrayList
、LinkedList
)加上一层 同步(synchronized)保护。
一、基本用法
java
List<Integer> list = new ArrayList<>();
List<Integer> syncList = Collections.synchronizedList(list);
这样得到的 syncList
是一个 线程安全 的 List
,在多线程场景下可以安全地增删改查。
二、源码解析(JDK 8)
来看 Collections
类的实现:
java
public static <T> List<T> synchronizedList(List<T> list) {
return (list instanceof RandomAccess ?
new SynchronizedRandomAccessList<>(list) :
new SynchronizedList<>(list));
}
如果底层 list
是随机访问的(例如 ArrayList
),则返回 SynchronizedRandomAccessList
;
否则返回 SynchronizedList
。这两个类结构几乎一样,都是对原 List
加锁包装。
关键类结构(内部静态类):
java
static class SynchronizedList<E>
extends SynchronizedCollection<E>
implements List<E> {
final List<E> list;
SynchronizedList(List<E> list) {
super(list);
this.list = list;
}
public void add(int index, E element) {
synchronized (mutex) {
list.add(index, element);
}
}
public E get(int index) {
synchronized (mutex) {
return list.get(index);
}
}
// 其他方法都加 synchronized(mutex)
}
三、执行流程说明
以 add()
为例:
java
List<Integer> syncList = Collections.synchronizedList(new ArrayList<>());
syncList.add(1);
执行过程:
1️⃣ 创建时,synchronizedList()
会把你的 ArrayList
包装成 SynchronizedList
对象。
2️⃣ 内部有一个共享锁对象 mutex
(通常就是 this
)。
3️⃣ 每次对 list
的操作(如 add()
、get()
、remove()
)都包裹在 synchronized (mutex)
块中。
4️⃣ 从而保证同一时间只有一个线程能访问这个列表。
四、和 CopyOnWriteArrayList
的区别
对比项 | Collections.synchronizedList() |
CopyOnWriteArrayList |
---|---|---|
实现方式 | 在每个方法外层加 synchronized 锁 |
写时复制:写操作复制新数组 |
读性能 | 所有操作都需加锁,读性能较低 | 读操作无锁,非常快 |
写性能 | 写锁竞争严重(串行化) | 写时复制成本高(需要复制整个数组) |
适用场景 | 写多读少 | 读多写少 |
迭代器行为 | 迭代时需要手动同步,否则可能抛异常 | 迭代是快照,不受修改影响 |
底层存储 | 原 List 对象 |
内部 volatile Object[] array |
✅ 五、使用迭代器的注意事项
java
List<Integer> syncList = Collections.synchronizedList(new ArrayList<>());
// 迭代时要手动加锁
synchronized (syncList) {
for (Integer i : syncList) {
System.out.println(i);
}
}
否则,多个线程同时迭代和修改时,可能导致 ConcurrentModificationException
。
✅ 六、小结
特性 | synchronizedList | CopyOnWriteArrayList |
---|---|---|
加锁机制 | 整体锁(synchronized) | 写时复制(volatile + CAS) |
读性能 | 慢(加锁) | 快(无锁) |
写性能 | 中(锁竞争) | 慢(复制数组) |
一致性 | 强一致 | 最终一致(读快照) |
使用场景 | 写多读少 | 读多写少 |