有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

嘿,所以古鲁的我有一个很好的工作与此代码

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)

仔细观察一下,这似乎是一个错误,通常情况下线程会发生,为什么它们会同时尝试访问同一个资源,但这就是为什么我在这个系统中根本不使用多线程

有人能解释为什么会发生这种情况,或者想出一个破解方法来绕过它吗

非常感谢^_^


共 (4) 个答案

  1. # 1 楼答案

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

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

    }

  2. # 2 楼答案

    如果从集合中删除内容,则不能使用for each循环
    您必须使用Iterator并删除当前项调用Iterator.remove

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

  3. # 3 楼答案

    在for循环下隐藏了一个人口迭代器。 在迭代器工作的中间,您正在从一个人口中移除一个项目。 迭代器不能再工作了,因为您在迭代过程中更改了集合。

    它与多线程无关

  4. # 4 楼答案

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

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