Strange ConcurrentModificationException行为

时间:2013-07-01 18:01:19

标签: java concurrentmodification

我不明白为什么这个方法会引发异常:

public void add(Object obj){
    gameObjects.add(obj); //here the exception happens
}

......虽然这个没有:

public void add(Object obj){
    gameObjects.add(obj); // no exception actually happens here 
    gameObjects.remove(obj);
}

为什么会发生这种情况,因为它是运行时异常?

例外:

Exception in thread "Thread-0" java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
    at java.util.ArrayList$Itr.next(Unknown Source)
    at threads.Main.tick(Main.java:181)
    at threads.Main.run(Main.java:104)

在对象内部调用tick方法。

gameObjects不为空:

List<Object> gameObjects = new ArrayList<Object>(128);

4 个答案:

答案 0 :(得分:3)

看起来你正试图在循环中添加它。 Java不允许这样做。如果你在同一个方法中添加然后删除,那么你实际上并没有做太多,净变化也没有什么不同,所以你不会在循环中尝试更改集合。

如果你想要它添加它,你将不得不使用迭代器。

答案 1 :(得分:2)

第一种方法抛出异常,因为您正在循环中修改某些集合。第二个不是因为集合没有净变化;你添加然后删除一个元素。

请注意,检查add的{​​{1}}方法不是ConcurrentModificationException。相反,在每次循环迭代结束时检查集合是否有任何修改。

答案 2 :(得分:0)

根据doc

  

检测到并发的方法可能抛出此异常   在不允许进行此类修改时修改对象。

     

例如,一个线程通常不允许修改   一个集合,而另一个线程正在迭代它。一般来说,   在这些情况下,迭代的结果是不确定的。   一些迭代器实现(包括所有通用的实现)   由JRE提供的目的集合实现可以选择   如果检测到此行为,则抛出此异常。那个迭代器   这被称为故障快速迭代器,因为它们很快就会失败   干净利落,而不是冒着任意的,非确定性的行为冒险   未来不确定的时间。

答案 3 :(得分:0)

遍历时,您无法更改相同的object

JavaDoc

  

此类的迭代器和listIterator返回的迭代器   方法是快速失败的:如果列表在结构上被修改了   创建迭代器之后的时间,除了通过之外的任何方式   迭代器自己删除或添加方法,迭代器会抛出一个   ConcurrentModificationException的。

有关详细信息,请访问以下链接。他们可以帮助你学习。

Concurrent Modification exception http://docs.oracle.com/javase/6/docs/api/java/util/ConcurrentModificationException.html