Java ConcurrentModificationException:单线程,两个不同的哈希表

Java ConcurrentModificationException:单线程,两个不同的哈希表,java,concurrentmodification,Java,Concurrentmodification,我得到了一个ConcurrentModificationException CME,它似乎不同于其他线程中要求的案例。我只运行一个线程。以下是我的代码片段(已编辑): CME出现在for语句中types属于Hashtable类型,是Obj类型的对象中的非静态成员变量other也属于Obj类型,代码段是Obj方法的一部分。就在for循环之前,我检查this和other,this.types和other.types,以及this.types.values()和other.types.values()

我得到了一个ConcurrentModificationException CME,它似乎不同于其他线程中要求的案例。我只运行一个线程。以下是我的代码片段(已编辑):

CME出现在
for
语句中
types
属于
Hashtable
类型,是
Obj
类型的对象中的非静态成员变量
other
也属于
Obj
类型,代码段是
Obj
方法的一部分。就在
for
循环之前,我检查
this
other
this.types
other.types
,以及
this.types.values()
other.types.values()
是成对不同的对象。(还通过Eclipse调试器中的不同对象ID进行验证)

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

@编辑:代码块来自一个更大的工具,它实际上支持多线程。线程数是可控的,仅选择单个线程时会出现此问题。同样在其方法中,代码被两个同步所包围:一个在
类型上,另一个在
其他.types上。所以,我想,这不是线程问题

该工具在Windows和Linux上运行。我们使用具有1.6兼容性级别的Java1.7。
(很抱歉,这不是我的错误代码)

如javadoc中所述:

当对象的并发修改不允许时,检测到该修改的方法可能会引发此异常。 例如,通常不允许一个线程在另一个线程迭代集合时修改集合。通常,在这些情况下,迭代的结果是未定义的。如果检测到此行为,某些迭代器实现(包括JRE提供的所有通用集合实现)可能会选择抛出此异常。这样做的迭代器称为fail-fast迭代器,因为它们快速、干净地失败,而不是在将来的不确定时间冒任意、不确定行为的风险

在使用时,实际上是在使用来浏览集合的元素。通常,如果您在创建迭代器后修改基础集合,迭代器的实现会抛出上述异常-在您的情况下,迭代器是集合上第一次迭代的创建者。使用“经典”for循环可以避免此问题:

for(int i=0; i< other.types.values().size(); i++) {
    types.put(t.getName(), t)
}

如果这两个是映射。

我已经测试过了,但无法重现此行为,请在代码段周围显示更多代码。顺便问一下,你怎么知道你只运行了一个线程?您是否使用任何库(Swing、GWT…)?你在哪里运行这个(Windows,Android…)?你的解决方案是绝对可取的。但是,他显式检查this.types!=其他.types实际上应该避免并发修改,因为他不会更改基础集合。或者我遗漏了什么?@Chnoch-抱歉,但我不明白为什么显式检查会对并发修改异常有所帮助。请您强调一下好吗?因为他迭代了其他.types,并在这个.types中添加了新项。在我看来,其他类型根本没有被修改。如果other.types和types是相同的引用,这是显而易见的,但是由于他检查对象的相等性,它们应该是不同的hashmap,因此other.types不会被修改,如果他只是向类型添加新元素的话。
for(int i=0; i< other.types.values().size(); i++) {
    types.put(t.getName(), t)
}
types.putAll(other.types)