我收到的ConcurrentModificationException CME似乎与其他线程中要求的情况不同。我只运行一个线程。这是我的代码片段(已编辑):
for(Type t : other.types.values()) {
types.put(t.getName(), t)
}
CME发生在for
声明中。 types
的类型为Hashtable<String, Type>
,是Obj
类型对象中的非静态成员变量。 other
也是Obj
类型,代码段是Obj
方法的一部分。在for
循环之前,我检查this
和other
,this.types
和other.types
,以及this.types.values()
和{{1}是成对不同的对象。 (还通过Eclipse调试器中的不同对象ID验证)。
CME是可重复的。我不知道在这种情况下会发生什么。
@Edit:代码片段来自一个更大的工具,它实际上支持多线程。线程数是可控的,仅在选择单个线程时会出现此问题。同样在其方法中,代码由两个同步包围:一个在other.types.values()
上,另一个在types
上。所以,我想,这不是一个线程问题。
该工具可在Windows和Linux上运行。我们使用1.6兼容级别的Java 1.7。 (对不起代码不好,这不是我的)
答案 0 :(得分:0)
正如ConcurrentModificationException的javadoc所述:
当不允许进行此类修改时,检测到对象的并发修改的方法可能抛出此异常。 例如,一个线程通常不允许修改Collection而另一个线程正在迭代它。通常,在这些情况下,迭代的结果是不确定的。如果检测到此行为,某些Iterator实现(包括JRE提供的所有通用集合实现的实现)可能会选择抛出此异常。执行此操作的迭代器称为失败快速迭代器,因为它们快速而干净地失败,而不是在未来的未确定时间冒着任意的,非确定性行为的风险。
当您使用foreach时,您实际上正在使用iterator来浏览集合的元素。通常,如果在创建迭代器之后修改底层集合,Iterator的实现会抛出提到的异常 - 在您的情况下,迭代器是集合上第一次迭代的创建者。使用“经典”for循环可以避免这个问题:
for(int i=0; i< other.types.values().size(); i++) {
types.put(t.getName(), t)
}
尽管如此,我认为您正在尝试将other.types
中的所有元素添加到types
,因为您可以这样做:
types.putAll(other.types)
如果这两个是地图。