非multithreading程序中的java.util.ConcurrentModificationException

嘿SO Guru我的这个代码有一份工作

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) 

稍微晃了一下这似乎是一个错误,通常会发生在线程为什么他们试图同时访问相同的资源,但这就是让我在这个系统中完全没有multithreading的原因。

有人可以解释为什么会发生这种情况,或者想到一个黑客可以绕过它

非常感谢^ _ ^

您可以修改Iterator的基础Collection (隐藏在for-each循环中)。 正确的方法是:

 for (Iterator 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循环在幕后为你创建的底层迭代器不会理解它正在经历的集合是如何变化的,告诉你在迭代它时它正在被更改。

你有一个在for循环下隐藏的迭代器。 您正在迭代器工作中删除一个项目。 迭代器不能再工作,因为你在迭代中间更改了集合。

它与multithreading无关。

解决方法可以复制集合。 迭代副本并从原始集合中删除元素。

 public void kill(double GrowthRate, int Death) { int before = population.size(); Collection forIteration = new HashSet(population); for (PopulationMember p : forIteration) { 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()); 

}