为什么此代码抛出ConcurrentModificationException?

时间:2016-08-26 12:35:40

标签: 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);
}

1 个答案:

答案 0 :(得分:5)

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

  

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

     

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

(重点补充)。

我猜tree.removeSubscriber(subtupel);正在修改其subscribers集。