非多线程程序中的java.util.ConcurrentModificationException

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (18)

即时通讯有一个这个代码的工作

public void kill(double GrowthRate, int Death)
{
    int before = population.size();
    for (PopulationMember p : population)
    {
        int[] probs = ProbablityArrayDeath(GrowthRate,Death,(int)p.fitness());
        if (probs[RandomNumberGen.nextRandomInt(0, 99)]==0)
        {
            population.remove(p);
        }
    }
    System.out.println("Intial Population: "+before+", Deaths:"+(before-          population.size())+", New Population: "+population.size());
}

当我第一次运行我的程序时,它会尝试运行代码,它会触发此错误

Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.HashMap$HashIterator.nextEntry(HashMap.java:793)
    at java.util.HashMap$KeyIterator.next(HashMap.java:828)
    at Genetics.Population.kill(Population.java:181)
    at Genetics.Population.run(Population.java:47)
    at Control.Main.main(Main.java:35)

经过一段时间的观察,这似乎是线程通常发生的一个错误,他们为什么会尝试同时访问同一资源,但这正是让我在这个系统中完全没有多线程的原因。

有人可以解释为什么会发生这种情况,或者想到解决它的办法

提问于
用户回答回答于

您可以修改底层CollectionIterator(这是隐藏在for-each环)。正确的做法是:

for (Iterator<PopulationMember> it = population.iterator(); it.hasNext();) {
    PopulationMemeber p = it.next();
    int[] probs = ProbablityArrayDeath(GrowthRate,Death,(int)p.fitness());
    if (probs[RandomNumberGen.nextRandomInt(0, 99)] == 0) {
        it.remove();
    }
}
用户回答回答于

for each如果您从集合中删除东西,则无法使用循环。 您必须使用Iterator和来移除当前的项目调用Iterator.remove

否则,for-each循环在幕后为你创建的底层迭代器不能理解它所经历的集合是如何变化的,告诉你它在迭代时正在被改变。

扫码关注云+社区