1.简介
1.CopyOnWrite是程序优化的策略,当共享的内容需要修改时,复制出去一份进行修改,然后将原来的引用指向修改完的
2.java并发包(java.util.concurrent)中CopyOnWriteArrayList和CopyOnWriteArraySet实现了这个并发容器
3.好处:因为写时是在复制的一份上操作,所以可以并发的读,不需要加锁,是读写分离的思想,在并发场景中使用
2.CopyOnWriteArrayList的实现原理
CopyOnWriteArrayList是一个线程安全,读操作时无锁的ArrayList
//构造函数,初始容量为0的数组
public CopyOnWriteArrayList() {
setArray(new Object[0]);
}
//添加新元素
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);//复制到一个新数组中,容量+1
newElements[len] = e;//添加新元素
setArray(newElements);//将原数组的引用指向新数组
return true;
} finally {
lock.unlock();
}
}
//读操作,不加锁
public E get(int index) {
return (E) (getArray()[index]);
}
3.CopyOnWrite的缺点:占用内存,因为要复制一份,可以压缩元素方法减少内存,当元素时10进制数时,压缩成64进制或者使用其 他并发容器 ConcurrnetHashMap
并发操作,读不到最新写入的数据,数据不一致
总结:线程安全,读操作不需要加锁
底层数据结构是Object[]数组,默认大小0.每次添加元素,容量+1,数组复制一遍
增删改上锁,读不上锁
遍历是遍历的全局数组的一个副本,不会发生并发异常
读多写少的情况且脏读的影响不大的并发情况,选择使用CopyOnWriteArrayList