ConcurrentModificationException:单线程,两个不同的Hashtables

时间:2014-09-30 07:11:59

标签: java concurrentmodification

我收到的ConcurrentModificationException CME似乎与其他线程中要求的情况不同。我只运行一个线程。这是我的代码片段(已编辑):

for(Type t : other.types.values()) {
    types.put(t.getName(), t)
}

CME发生在for声明中。 types的类型为Hashtable<String, Type>,是Obj类型对象中的非静态成员变量。 other也是Obj类型,代码段是Obj方法的一部分。在for循环之前,我检查thisotherthis.typesother.types,以及this.types.values()和{{1}是成对不同的对象。 (还通过Eclipse调试器中的不同对象ID验证)。

CME是可重复的。我不知道在这种情况下会发生什么。

@Edit:代码片段来自一个更大的工具,它实际上支持多线程。线程数是可控的,仅在选择单个线程时会出现此问题。同样在其方法中,代码由两个同步包围:一个在other.types.values()上,另一个在types上。所以,我想,这不是一个线程问题。

该工具可在Windows和Linux上运行。我们使用1.6兼容级别的Java 1.7。 (对不起代码不好,这不是我的)

1 个答案:

答案 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)

如果这两个是地图。