CopyOnWriteArrayList中add有锁了为什么要copy
看之前一定要去看之前juc常用中看下volatile的作用
主要还是看写操作,下面是他的源码
/**
* Appends the specified element to the end of this list.
*
* @param e element to be appended to this list
* @return {@code true} (as specified by {@link Collection#add})
*/
public boolean add(E e) {
synchronized (lock) {
Object[] es = getArray();
int len = es.length;
es = Arrays.copyOf(es, len + 1);
es[len] = e;
setArray(es);
return true;
}
}
疑问点::为什么加锁了还要进行copy操作
思考::
1、若没有复制,写时加锁,读时不加锁,那么就会发生并发读写问题,产生不可预期的异常,即上面说的 ConcurrentModificationException;
2、若没有复制,写时加锁,读时也需要加锁,这样就相当于退化为 SynchronizedList,读性能大大减弱。
解答::
先看上述代码中有volatile修饰
那你add了,将指向新的值,其他线程读取出来的也是最新的
由于读没有加锁,而volatile并不保证原子性,写的过程中的数据修改会被其他线程看到。
volatile:
可见性:当一个线程修改一个 volatile 变量的值时,这个新值将立即被写入主内存(Main Memory),并且对其他线程可见。当其他线程读取该 volatile 变量时,它们将会从主内存中读取最新的值,而不是使用线程的本地缓存。