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,也是很多并发场景下解决性能问题很好的思路。
0条评论