關於 CopyOnWrite ArrayList

關於CopyOnWriteArrayList

當有需要對List同時讀和寫操作時,我們會需要使用CopyOnWriteArrayList。

對ArrayList同時做讀和寫操作時會java.lang.RuntimeException: java.util.ConcurrentModificationException

1
2
3
4
5
6
7
8
在程式啟動執行緒時會一邊讀資料一邊寫資料,這樣有可能在執行這支程式的時侯發生 Exception,如下:

Exception in thread "main" java.lang.RuntimeException: java.util.ConcurrentModificationException
at com.company.Main.main(Main.java:24)
Caused by: java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)
at java.util.ArrayList$Itr.next(ArrayList.java:859)
at com.company.Main.main(Main.java:20)

CopyOnWriteArrayList 是在Read的時侯複製出一份相同的資料內容,這樣就避免了同時讀寫一個 List 遇到的問題

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import java.util.concurrent.CopyOnWriteArrayList;

public class Main {

public static void main(String[] args) {
try {
final CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<String>();
list.add("a1");
list.add("a2");
list.add("a3");
list.add("a4");
list.add("a5");
list.add("a6");

Thread thread = new Thread(new ThreadExample(list));
thread.start();

for(String s: list) {
System.out.println(s);
}
} catch(Exception e) {
throw new RuntimeException(e);
}
}
}

使用情境

1
2
使用 CopyOnWriteArrayList 適合的使用情境是當資料讀取的次數比寫入的次數還多的時侯,
因為寫入的資料不多 copy 的大小也不會太大,所以在此情況下執行的效能會較好。