CopyOnWriteArrayList简介

ArrayList是很常用的一个数据结构,我们知道它不是线程安全的,在线程安全环境,我们可以用Vector。

Vector虽然是安全的,但是并发下性能不高。

CopyOnWriteArrayList是线程安全的ArrayList,在读多写少的场景下,他的性能非常好。

结合源码分析CopyOnWriteArrayList性能高的原因

内部实际存储的数组

private transient volatile Object[] array;

可以看到读操作是无锁的,所以性能很高

public E get(int index) {  
    return get(getArray(), index);  
}

private E get(Object[] a, int index) {  
    return (E) a[index];  
}

写入请求通过锁来串行化,在写入之前先把原数据复制一份到新数组,在新数组执行写入,再替换原数组

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的实现机制是,读操作无锁化,写操作使用复制后操作的串行化方式来实现。提高了读操作性能的同时,对于写操作来说,每次都需要复制一份数组拷贝,效率变低。所以,这个类非常适用于读多写少,并且有线程安全要求的场景。

CopyOnWrite思想

在多线程环境,通常都需要用锁来保证线程安全,读写锁是一个比较常用的方案。

CopyOnWrite的这种方案,在某些场景下是非常高效的。

这种读无锁化,通过复制来进行写入修改的思想,不仅可以用在CopyOnWriteArrayList,也是很多并发场景下解决性能问题很好的思路。