为什么此代码抛出ConcurrentModificationException?

Him*_*mah 1 java

下面是代码,即使我没有修改底层集合并将其作为单个线程运行,我ConcurrentModificationException也在subiter.next()调用中.

Tree tree=partition.getTreeofThisPartition();
Set<DzExpressionHostTupel> oldSubtupels=tree.getSubscribers();
Iterator<DzExpressionHostTupel> subiter=oldSubtupels.iterator();           
while (subiter.hasNext()){
    DzExpressionHostTupel subtupel=subiter.next();
    tree.removeSubscriber(subtupel);
}
Run Code Online (Sandbox Code Playgroud)

Tay*_*lor 5

如果您阅读https://docs.oracle.com/javase/7/docs/api/java/util/ConcurrentModificationException.html,它会说:

例如,一个线程通常不允许修改Collection而另一个线程正在迭代它.通常,在这些情况下,迭代的结果是不确定的.如果检测到此行为,某些Iterator实现(包括JRE提供的所有通用集合实现的实现)可能会选择抛出此异常.执行此操作的迭代器称为失败快速迭代器,因为它们快速而干净地失败,而不是在未来的未确定时间冒着任意的,非确定性行为的风险.

请注意,此异常并不总是表示某个对象已被另一个线程同时修改.如果单个线程发出违反对象合同的一系列方法调用,则该对象可能会抛出此异常.例如,如果线程在使用失败快速迭代器迭代集合时直接修改集合,则迭代器将抛出此异常.

(重点补充).

我猜tree.removeSubscriber(subtupel);是正在修改它的subscribers设置.

  • 他没有两个线程,但他在迭代期间交叉修改数据结构. (2认同)