2011-04-13 36 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方法。这意味着,当您在循环中添加新元素时,列表实际上会被修改。如果在添加新元素后退出循环,则不会抛出异常并将元素添加到列表中。

否则,你可以使用迭代器的添加和删除的方法来修改循环内的列表。