java.util.ConcurrentModificationException in Non Multithreaded Program

自作多情 提交于 2019-11-27 20:34:34

问题


Hey SO Guru's im having one heck of a job with this code

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 ^_^


回答1:


You can modify the underlying Collection of the Iterator (which is hidden in the for-each loop). The proper way to do this is:

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();
    }
}



回答2:


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.

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.




回答3:


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.

It's not related to multithreading.




回答4:


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());

}



来源:https://stackoverflow.com/questions/1816196/java-util-concurrentmodificationexception-in-non-multithreaded-program

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!