CopyOnWriteArrayList 写时拷贝

296 阅读1分钟

CopyOnWriteArrayList 写时拷贝

特点

  • 写操作都会复制一个新的数组
  • 线程安全
  • 适用于高并发读,少量写的场景(读不需要加锁,写需要加锁)
  • 读写分离
  • 数据最终一致

源码

基于可重入锁和数组实现

public class CopyOnWriteArrayList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
    private static final long serialVersionUID = 8673264195747942595L;

    /** The lock protecting all mutators */
    transient final ReentrantLock lock = new ReentrantLock();

    /** The array, accessed only via getArray/setArray. */
    private volatile transient Object[] array;

}

以新增为例,新增时先获取锁,然后复制原数组数据到一个新的长度加1的数组,将新元素加入到新数组,更改数组的引用。

新增时需要加锁,并且是操作的新数组,所以并不影响读操作,读时不需要加锁可以并发读,只是读的可能不是最新数据,但保证数据的最终一致性。

 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();
        }
    }

CopyOnWriteArraySet 是基于 CopyOnWriteArrayList实现的并发Set集合