2. CopyOnWriteArrayList
CopyOnWriteArrayList是什么呢艳丛?顧名思義瓢剿,先Copy后Write(將原來的array復(fù)制到新的array)丹锹,也就是說對于CopyOnWriteArrayList柬讨,任何可變的操作(add表锻、set、remove等等)都是通過ReentrantLock 控制并發(fā)并伴隨復(fù)制這個(gè)動(dòng)作威鹿。
看一下add操作怎么實(shí)現(xiàn)的
public boolean add(E e) {
final ReentrantLock lock = this.lock;
//獲得鎖
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
//復(fù)制一個(gè)新的數(shù)組
Object[] newElements = Arrays.copyOf(elements, len + 1);
//插入新值
newElements[len] = e;
//將新的數(shù)組指向原來的引用
setArray(newElements);
return true;
} finally {
//釋放鎖
lock.unlock();
}
}
看完明白了妓盲,上個(gè)鎖自己復(fù)制、修改专普、賦值嘛悯衬,這就厲害了,Vector是增刪改查方法都加了synchronized,保證同步筋粗,但是每個(gè)方法執(zhí)行的時(shí)候都要去獲得鎖策橘,性能就會大大下降,而CopyOnWriteArrayList 只是在增刪改上加鎖娜亿,但是讀不加鎖丽已,在讀方面的性能就好于Vector,CopyOnWriteArrayList支持讀多寫少的并發(fā)情況买决,快快試一下先:
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);
}
執(zhí)行結(jié)果:
可以看出list的數(shù)據(jù)已經(jīng)改變了沛婴,但是遍歷的結(jié)果為什么“測試2”還在?這就是因?yàn)樗鹀opy的原因督赤,實(shí)際的list數(shù)據(jù)已經(jīng)改變了嘁灯,但是此次遍歷的數(shù)據(jù)還是之前的list,所以導(dǎo)致此現(xiàn)象躲舌。