CopyOnWriteArrayList
?java.util.concurrent
包下的 线程安全的 Listvolatile Object[] array
ReentrantLock
互斥锁volatile
保证可见性)add()
)public boolean add(E e) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
Object[] newElements = Arrays.copyOf(elements, len + 1);
newElements[len] = e;
setArray(newElements);
return true;
} finally {
lock.unlock();
}
}
可以看到: ✅ 每次写都是复制一份新数组
✅ 写的时候加锁
✅ 读的时候完全无锁直接读取数组
读多写少 比如:
读操作 非常频繁,写操作 偶尔才发生
优点 ✅ | 缺点 ❌ |
---|---|
读操作无锁,性能极高 | 写操作开销大,涉及数组复制(O(n)) |
读写分离,读操作不会阻塞 | 不适合高并发写场景(大量写时性能很差) |
线程安全,避免并发修改异常(fail-safe ) |
内存占用大,频繁写会导致大量冗余对象产生 |
读不加锁,直接基于 volatile array
读取,超快!
ConcurrentModificationException
?因为写操作直接复制新数组,读操作永远看旧数组,天然 fail-safe
。
ArrayList
区别?特性 | ArrayList | CopyOnWriteArrayList |
---|---|---|
线程安全 | ❌ 否 | ✅ 是 |
读性能 | 快 | 快(无锁) |
写性能 | 快 | 慢(需要复制) |
适用场景 | 单线程 or 手动加锁 | 读多写少并发场景 |
for (String s : cowList) {
// 安全,遍历的是旧数组
}
import java.util.concurrent.CopyOnWriteArrayList;
public class Demo {
public static void main(String[] args) {
CopyOnWriteArrayList list = new CopyOnWriteArrayList<>();
list.add("A");
list.add("B");
list.add("C");
// 读操作无锁,超快
list.forEach(System.out::println);
// 写时复制,线程安全
list.add("D");
}
}
CopyOnWriteArrayList 是线程安全的 List,核心是写时复制(Copy-On-Write)。
读操作无锁,性能高;写操作加锁并复制新数组,适合读多写少场景。
天然避免 ConcurrentModificationException,遍历安全。