質問

このコードを使用して、ちょっと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)

少し回ってみると、これは通常、スレッドが同じリソースに同時にアクセスしようとするスレッドで発生するエラーのように見えますが、これがこのシステムでマルチスレッドではないことです。

なぜこれが起こっているのかを説明したり、それを回避するためのハックを考えたりできます

本当にありがとう^ _ ^

役に立ちましたか?

解決

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

他のヒント

コレクションからものを削除する場合、 for each ループを使用できません。
Iterator を使用し、現在のアイテムを削除するには、 Iterator.remove を呼び出す必要があります。

それ以外の場合、for-eachループが背後であなたのために作成する基礎となるイテレーターは、通過するコレクションがどのように変化するのかを理解せず、反復中に変更されていることを伝えます。

forループの下に隠されたポピュレーションのイテレータがあります。 イテレータの動作中に母集団からアイテムを削除しています。 反復の途中でコレクションを変更したため、イテレーターは機能しなくなります。

マルチスレッドとは関係ありません。

回避策はコレクションをコピーすることです。コピーを繰り返し処理し、元のコレクションから要素を削除します。

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

}

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top