當使用 fail-fast iterator 對 Collection 或 Map 進行迭代操作過程中嘗試直接修改 Collection /
Map 的內容時,即使是在單線程下運行, java
.util
.ConcurrentModificationException
異常也將被拋出。
Iterator 是工作在一個獨立的線程中,並且擁有一個 mutex 鎖。 Iterator
被創建之後會建立一個指向原來對象的單鏈索引表,當原來的對象數量發生變化時,這個索引表的內容不會同步改變,所以當索引指針往後移動的時候就找不到要迭
代的對象,所以按照 fail-fast 原則 Iterator 會馬上拋出 java
.util
.ConcurrentModificationException
異常。
所以 Iterator 在工作的時候是不允許被迭代的對象被改變的。但你可以使用 Iterator 本身的方法
remove() 來刪除對象, Iterator.remove() 方法會在刪除當前迭代對象的同時維護索引的一致性。
有意思的
是如果你的 Collection / Map 對象實際只有一個元素的時候, ConcurrentModificationException
異常並不會被拋出。這也就是爲什麼在 javadoc 裏面指出: it would be wrong to write a program
that depended on this exception for its correctness: ConcurrentModificationException
should be used
only to detect bugs.
1 import java
.util
.*;
2
3 public final class
MyTest
4 {
5 private static HashMap p_mapList = new
HashMap(2);
6 private MyTest(){}
7 public static
void init(){
8 // If only there are more than one element
in Map,
9 // the ConcurrentModificationException
will not be
10 // thrown.
11 p_mapList.put(new
String("hello"),new String("world"));
12
p_mapList.put(new String("goto"),new String("hell"));
13 }
14
public static void clear() throws Exception{
15
Iterator pTmpKeys = null;
16 Long pTmpKeyLong;
17
pTmpKeys = p_mapList.keySet().iterator();
18
String pCurKey = null;
19 String pCurObj = null;
20
while(pTmpKeys.hasNext()){
21 pCurKey =
(String) pTmpKeys.next();
22 pCurObj = (String)
p_mapList.get(pCurKey);
23
24
p_mapList.put(pCurKey,null);
25 // You can not remove
element in Map object directly.
26
//p_mapList.remove(pCurKey);
27 // But you can remove
current element by iterator itself.
28
pTmpKeys.remove();
29
30
System.out.println(pCurKey + " removed.");
31 }
32
System.out.println(p_mapList.size() +
33
" entries left after iterator.");
34
pTmpKeys = null;
35 }
36 public static
void main(String[] args)
37
throws Exception{
38 MyTest.init();
39
MyTest.clear();
40 }
41 }
關於Map表循環過程刪除操作出現的java.util.ConcurrentModificationException 異常
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.