什么是CopyOnWrite容器?
CopyOnWrite容器即写时复制的容器。通俗的理解是当我们往一个容器添加元素的时候,不直接往当前容器添加,而是先将当前容器进行Copy,复制出一个新的容器,然后新的容器里添加元素,添加完元素之后,再将原容器的引用指向新的容器。这样做的好处是我们可以对CopyOnWrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素。所以CopyOnWrite容器也是一种读写分离的思想,读和写不同的容器。
重点容器维护的数组使用volatile修饰的,保证及时可见性!
添加的源码
private transient volatile Object[] array;//原集合数组用volatile修饰
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添加数据,读还是会读到旧的数据,因为写的时候不会锁住旧的
public E get(int index) {
return get(getArray(), index);
}
CopyOnWrite的应用场景
读多写少的情况;
CopyOnWrite的缺点
1::内存占用变多,因为维护了2份相同的数组。
2:数据一致性问题,在读取的时候,可能是从旧的数组读取到的。