2011-04-13 67 views
4

時獲得ConcurrentException。我有一個像下面的列表的東西: -穿越我在一個非常特殊的狀態列表

List<String> list = new ArrayList<String>(); 
list.add("a"); 
list.add("b"); 

現在,當我做多的類型遍歷,如採用先進的,迭代器,以及正常的循環,下面是示例代碼片段: -

1 >高級循環: -

try { 
    for(String a : list) { 
     System.out.println(a); 
     list.add("f"); 
    } 
} catch (Exception e) { 
    e.printStackTrace(); 
} 

2>迭代: -

try { 
    Iterator<String> itr = list.iterator(); 
    while(itr.hasNext()) { 
     System.out.println(itr.next()); 
     list.add("f"); 
    } 
} catch (Exception e) { 
    e.printStackTrace(); 
} 

3>正常循環: -

for (int i=0;i<list.size();i++) { 
    System.out.println(list.get(i)); 
    list.add("f"); 
} 

現在,特有的問題是,採用了先進的當for循環和迭代,我得到以下異常: -

java.util.ConcurrentModificationException 
    at java.util.ArrayList$Itr.checkForComodification(Unknown Source) 
    at java.util.ArrayList$Itr.next(Unknown Source) 


the reason i know, that while iterating through a list, one cannot modify it parallely. 

但是當我用正常的循環,那麼它的工作原理好吧,我是否缺少什麼?

請幫忙!!! ..

回答

7

如果你修改一個List,它將使從它創建的任何Iterator對象失效。高級循環(1)編譯爲與迭代器循環(2)幾乎相同的代碼,這意味着在場景後面創建了一個Iterator對象。

ConcurrentMOdificationException的javadoc有更多的細節。

如果你想在迭代添加,使用

ListIterator listIter = ... 
while(listIter.hasNext()) 
{ 
    if(shouldAdd(iter.next())) { 
     iter.add(....) 
    } 
} 
+0

那麼怎麼樣的正常循環,爲什麼它的工作原理? – 2011-04-13 04:59:14

+0

添加無效由List創建的Iterator對象,正常for循環不會創建迭代器,因此沒有任何操作失效,因此它可以工作 – sbridges 2011-04-13 05:04:40

3

先進的循環僅僅是迭代器語法糖。迭代器在運行時始終調用checkForComodification()next()。如果發現您修改了列表,該方法將引發異常。

運行「正常循環」不提供,因爲你不使用一個迭代循環檢查修改計數此功能,嚴格使用的循環結構。

0

名單上做一個for循環會造成嚴重的問題。您將重新讀取條目(刪除以前的條目可能會導致此問題),您可能會收到IndexOutOfBoundsExceptions。根據您的應用程序,使用CopyOnWriteArrayList作爲併發安全列表,開銷並不多。如果您有很多寫入列表,請使用ConcurrentLinkedQueue,但請注意,它的行爲就像是一個隊列,您只能使用類似隊列的東西,例如只添加到結尾並從前面移除。

0

您應該記住,迭代器的下一個方法拋出ConcurrentModificationException,而不是List的add方法。這意味着,當您在循環中添加新元素時,列表實際上會被修改。如果在添加新元素後退出循環,則不會拋出異常並將元素添加到列表中。

否則,你可以使用迭代器的添加和刪除的方法來修改循環內的列表。