2. CopyOnWriteArrayList
CopyOnWriteArrayList是什么呢?顾名思义,先Copy后Write(将原来的array复制到新的array),也就是说对于CopyOnWriteArrayList,任何可变的操作(add、set、remove等等)都是通过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();
}
}
看完明白了,上个锁自己复制、修改、赋值嘛,这就厉害了,Vector是增删改查方法都加了synchronized,保证同步,但是每个方法执行的时候都要去获得锁,性能就会大大下降,而CopyOnWriteArrayList 只是在增删改上加锁,但是读不加锁,在读方面的性能就好于Vector,CopyOnWriteArrayList支持读多写少的并发情况,快快试一下先:
CopyOnWriteArrayList<String> copyOnWriteArrayList = new CopyOnWriteArrayList();
for (int i = 1; i < 6; i++) {
copyOnWriteArrayList.add("测试" + i);
}
for (String strCopyList : copyOnWriteArrayList) {
copyOnWriteArrayList.remove("测试2");
Log.d(TAG, "---strCopyList---" + strCopyList);
Log.d(TAG, "---copyOnWriteArrayList---" + copyOnWriteArrayList);
}
执行结果:
执行结果
可以看出list的数据已经改变了,但是遍历的结果为什么“测试2”还在?这就是因为他copy的原因,实际的list数据已经改变了,但是此次遍历的数据还是之前的list,所以导致此现象。
网友评论