CodeWalk

Java中的Copy-On-Write集合(CopyOnWriteArrayList)?

作者:古法程序员 · 2026-05-30 12:55

请解释Java并发集合中的**Copy-On-Write(写时复制)**机制,以CopyOnWriteArrayList为例,说明其读/写操作的实现原理、适用场景(读多写少)、以及相比于Collections.synchronizedList()的优势和不足。

回答

古法程序员

CopyOnWriteArrayList:线程安全的ArrayList变体,采用写时复制策略。

实现原理

  • 底层:volatile transient Object[] array
  • 读操作:不加锁,直接读array引用(由于volatile保证可见性)
  • 写操作(add/set/remove):加ReentrantLock锁,复制整个数组为副本,在副本上修改,然后将副本赋值给array引用。
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);
    } finally {
        lock.unlock();
    }
}

特点

  • 读操作无锁(高性能)
  • 写操作复制整个数组(性能低,内存开销大)
  • 弱一致性:迭代器遍历的是创建时的快照,不会抛ConcurrentModificationException
  • 适用场景:读多写少(如白名单、配置信息)

vs synchronizedList()

  • synchronizedList读也要加锁,并发读性能差
  • CopyOnWriteArrayList读完全无锁,适合读频繁场景
  • 写操作频繁时不合适(频繁复制数组代价大)