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

发布于 2024-08-12 14:24:25 字数 1062 浏览 9 评论 0原文

嘿,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)

经过一番观察,这似乎是一个通常发生在线程中的错误,为什么他们会尝试并同时访问相同的资源,但这就是让我在这个系统中根本不使用多线程的原因。

有人可以解释为什么会发生这种情况,或者想办法解决它,

非常感谢^_^

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

雾里花 2024-08-19 14:24:25

您可以修改Iterator 的底层Collection(隐藏在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();
    }
}

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();
    }
}
筱果果 2024-08-19 14:24:25

如果从集合中删除内容,则无法使用 foreach 循环。
您必须使用 Iterator 并调用 Iterator.remove 来删除当前项。

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

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.

童话里做英雄 2024-08-19 14:24:25

你有一个隐藏在 for 循环下的人口迭代器。
您正在迭代器工作期间从总体中删除一个项目。
迭代器无法再工作,因为您在迭代过程中更改了集合。

它与多线程无关。

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.

謸气贵蔟 2024-08-19 14:24:25

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

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

}

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

}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文