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
?
?