2013-07-25 60 views

回答

74

由於這個link說:

CopyOnWriteArrayList是Java 5併發API在Java其廣受歡迎的表弟的ConcurrentHashMap一起引入併發集合類。

CopyOnWriteArrayList實現List接口像ArrayList,Vector和LinkedList,但它是一個線程安全的集合,它以與Vector或其他線程安全的集合類稍微不同的方式實現其線程安全。

如名稱建議CopyOnWriteArrayList創建基礎的拷貝 ArrayList與每個變異操作,例如,添加或設置。通常 CopyOnWriteArrayList是非常昂貴的,因爲它涉及昂貴的 陣列拷貝與每個寫操作,但它非常有效,如果你 有一個列表,其中迭代數量超過突變例如,你主要需要 迭代ArrayList,不要經常修改它。

的CopyOnWriteArrayList的迭代器是故障安全和即使底層 的CopyOnWriteArrayList一次迭代開始,因爲 迭代器上的ArrayList的單獨副本操作修改不會拋出 ConcurrentModificationException的。因此,所有 CopyOnWriteArrayList上進行的更新不可用於迭代器。

要獲得最新版本做了新的念想list.iterator();

話雖這麼說,更新這個集合了很多會殺了性能。如果您嘗試對CopyOnWriteArrayList進行排序,您將看到該列表將引發UsupportedOperationException異常(該排序在集合上調用集N次)。只有在讀數超過90%時,才應使用此讀數。

+0

如果您需要非常頻繁地將項目添加到列表中,有時需要刪除所有項目。你認爲'同步'的方式是更好的方法嗎? –

+2

你可以考慮'Collections.synchronizedList'上的'java.util.concurrent'包。 –

+0

我已經在使用它。但它似乎只是當我結合舊的'synchronized'關鍵字時才起作用。 –

20

應對新陣列的目的是什麼?

複製底層數組可以保證數據結構的任何迭代都是安全的,因爲迭代發生在數據本質上不可變的「快照」上。

是否讓其他線程讀取數組?

的排序。更具體地說,每個線程都可以安全地迭代數組,而不用擔心ConcurrentModificationException或其他未知/未定義的行爲。

因此,如果一個系統的併發性很高,並且大多數線程的操作正在讀取而不是寫入,那麼最好使用CopyOnWriteArrayList。我對嗎?

只有當大多數線程的動作都在列表上迭代時。如果大多數活動都是基於隨機訪問的讀取,則ReadWriteLock可能會更好。

CopyOnWriteArrayList

這通常是過於昂貴的Javadoc,但可能比替代品時遍歷操作遠多於突變更有效,並且是有用的,當你不能或不想進行同步遍歷,但需要排除併發線程之間的干擾。

+0

你能解釋爲什麼'ReadWriteLock'可能會更好嗎? – damluar

+4

因爲'CopyOnWriteArrayList'用於安全遍歷。使用它的代價是複製每個修改的基礎引用數組,並且可能保留多個線程迭代,以迭代結構的陳舊版本。一個'ReadWriteLock'將允許多個讀者,並讓偶爾的作者進行必要的修改。 –

相關問題