什么是CopyOnWrite容器?
CopyOnWrite容器即写时复制的容器。简单来讲是当我们往一个容器添加元素的时候,不直接往当前容器添加,而是先将当前容器进行Copy,复制出一个新的容器,然后新的容器里添加元素,添加完元素之后,再将原容器的引用指向新的容器。
这样做的好处是我们可以对CopyOnWrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素。所以CopyOnWrite容器也是一种读写分离的思想,读和写不同的容器。
比较典型的CopyOnWriteArrayList和CopyOnWriteArraySet就是写时复制容器。
CopyOnWriteArrayList类图

我们进入CopyOnWriteArrayList#add方法,查看源码,可以看到它的的底层依旧是数组,基于ReentrantLock来做并发控制
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();}}
set()
public E set(int index, E element) {// 获得锁final ReentrantLock lock = this.lock;lock.lock();try {Object[] elements = getArray();E oldValue = get(elements, index);if (oldValue != element) {int len = elements.length;Object[] newElements = Arrays.copyOf(elements, len);newElements[index] = element;setArray(newElements);} else {// Not quite a no-op; ensures volatile write semanticssetArray(elements);}return oldValue;} finally {lock.unlock();}}
