java.util.ConcurrentModificationException in Non Multithreaded Program

Gwilym picture Gwilym · Nov 29, 2009 · Viewed 20.7k times · Source

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

Answer

Bozho picture Bozho · Nov 29, 2009

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