根据我的理解,并发集合类比同步集合更可取,因为并发集合类不会锁定完整的集合对象。相反,它们在收集对象的一小部分上锁定。

但是,当我检查addCopyOnWriteArrayList方法时,我们获得了对完整集合对象的锁定。那么CopyOnWriteArrayList怎么比Collections.synchronizedList返回的列表更好呢?我在addCopyOnWriteArrayList方法中看到的唯一区别是,每次调用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();
    }
}

最佳答案

对于写(添加)操作,CopyOnWriteArrayList使用ReentrantLock并创建数据的备份副本,并且仅通过setArray来更新基础的 volatile 数组引用(在setArray之前的列表上的任何读取操作都将在添加之前返回旧数据)。 CopyOnWriteArrayList提供快照故障安全迭代器,并且在写入/添加操作时不会引发ConcurrentModifficationException。


  • 不,该锁不在整个Collection对象上。如上所述,它是ReentrantLock,它与内部对象锁不同。
  • add方法将始终创建现有数组的副本并对该副本进行修改,然后最终更新该数组的volatile引用以指向此新数组。这就是为什么我们使用名称“CopyOnWriteArrayList”的原因,当您将其写入时将进行复制。这也避免了ConcurrentModificationException
  • 10-08 19:54