非多线程程序中的 java.util.ConcurrentModificationException
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1816196/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
java.util.ConcurrentModificationException in Non Multithreaded Program
提问by Gwilym
Hey SO Guru's im having one heck of a job with this code
嘿,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());
}
When I run my program the first time it tries to run the code it hits this error
当我第一次运行我的程序时,它尝试运行代码时遇到此错误
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)
Having goggled around a bit this seems to be an error that normally happens with threads why they try and access the same resource concurrently, but this is what getting me im not multithreading at all in this system.
仔细观察了一下,这似乎是线程通常会发生的错误,为什么它们会尝试并发访问相同的资源,但这就是让我在这个系统中根本不是多线程的原因。
Can someone explain why this is happening, or think of a hack to get around it
有人可以解释为什么会发生这种情况,或者想办法绕过它
Many thanks ^_^
非常感谢^_^
采纳答案by Bozho
You can modify the underlying Collection
of the Iterator
(which is hidden in the for-each
loop).
The proper way to do this is:
您可以修改底层Collection
的Iterator
(这是隐藏在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();
}
}
回答by abyx
You can't use the for each
loop if you remove things from the collection.
You have to use an Iterator
and to remove the current item call Iterator.remove
.
for each
如果从集合中删除内容,则无法使用循环。
您必须使用Iterator
and 删除当前项目调用Iterator.remove
。
Otherwise, the underlying iterator that the for-each loop creates for you behind the scenes doesn't understand how come the collection it's going through is changing, tells you that it is being changed while you iterate it.
否则,for-each 循环在幕后为您创建的底层迭代器不了解它正在经历的集合是如何改变的,它会在您迭代它时告诉您它正在改变。
回答by Yoni Roit
You've got an iterator over population hidden under a for loop. You are removing an item from population in the middle of iterator working. Iterator can't work no more because you changed the collection in the middle of it iterating.
你有一个隐藏在 for 循环下的人口迭代器。您正在迭代器工作期间从人口中删除一个项目。Iterator 不能再工作了,因为您在迭代过程中更改了集合。
It's not related to multithreading.
它与多线程无关。
回答by Eugene Platonov
A workaround can be copy a collection. Iterate over the copy and remove elements from the original collection.
解决方法可以是复制集合。迭代副本并从原始集合中删除元素。
public void kill(double GrowthRate, int Death) {
int before = population.size();
Collection<PopulationMember> forIteration = new HashSet<PopulationMember>(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());
}
}