寫入時複製(CopyOnWrite,簡稱COW)思想是計算機程序設計領域中的一種優化策略。其核心思想是,若是有多個調用者(Callers)同時要求相同的資源(如內存或者是磁盤上的數據存儲),他們會共同獲取相同的指針指向相同的資源,直到某個調用者試圖修改資源內容時,系統纔會真正複製一份專用副本(private copy)給該調用者,而其餘調用者所見到的最初的資源仍然保持不變。這過程對其餘的調用者都是透明的(transparently)。此作法主要的優勢是若是調用者沒有修改資源,就不會有副本(private copy)被建立,所以多個調用者只是讀取操做時能夠共享同一份資源。數組
歸納一下CopyOnWriteArrayList源碼註釋介紹了什麼:安全
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; // 將volatile Object[] array 的指向替換成新數組 setArray(newElements); return true; } finally { lock.unlock(); } }
====在添加的時候就上鎖,並複製一個新數組,增長操做在新數組上完成,將array指向到新數組中,最後解鎖。
對於remove()、clear()
跟set()和add()
是相似的優化
部分源碼:this
/** The lock protecting all mutators */ final transient ReentrantLock lock = new ReentrantLock(); /** The array, accessed only via getArray/setArray. */ private transient volatile Object[] array; /** * Gets the array. Non-private so as to also be accessible * from CopyOnWriteArraySet class. */ final Object[] getArray() { return array; } /** * Sets the array. */ final void setArray(Object[] a) { array = a; }
array 數組是被 volatile修飾的,修改後其餘線程可當即察覺到這個修改spa
volatile :(揮發物、易變的):變量修飾符,只能用來修飾變量。修飾的成員變量在每次被線程訪問時,都強迫從共享內存中重讀該成員變量的值。並且,當成員變量發生變 化時,強迫線程將變化值回寫到共享內存。這樣在任什麼時候刻,兩個不一樣的線程老是看到某個成員變量的同一個值。
transient:(暫短的、臨時的):修飾符,只能用來修飾字段。在對象序列化的過程當中,標記爲transient的變量不會被序列化。線程
總結:設計
缺點:指針
add()、set()、remove()
的話,那是比較耗費內存的