java.util.ConcurrentModificationException في برنامج غير متعددة مؤشرات الترابط

StackOverflow https://stackoverflow.com/questions/1816196

سؤال

ويا SO ايم جورو وجود واحدة من هيك وظيفة مع هذا الرمز

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)

وبعد أن حملق في جميع أنحاء قليلا يبدو أن هذا خطأ يحدث عادة مع المواضيع السبب في أنها محاولة الوصول إلى نفس الموارد في وقت واحد، ولكن هذا هو ما يحصل لي ايم ليس خاصية تعدد على الإطلاق في هذا النظام.

ويمكن للشخص أن يفسر لماذا يحدث هذا، أو التفكير في الإختراق للحصول على من حوله

وشكرا جزيلا ^ _ ^

هل كانت مفيدة؟

المحلول

ويمكنك تعديل Collection الكامنة وراء Iterator (التي كانت مخبأة في حلقة 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 الدعوة البند.

وخلاف ذلك، فإن مكرر الأساسي أن مقابل كل حلقة يخلق لك وراء الكواليس لا يفهم كيف تأتي جمع انه سيكون من خلال يتغير، يخبرك أن يتم تغييره أثناء تكرار ذلك.

ولقد حصلت على مكرر على السكان مخبأة تحت لحلقة. كنت إزالة عنصر من السكان في منتصف العمل مكرر. مكرر لا يمكن أن تعمل لا أكثر لأنك غيرت جمع في وسطها بالتكرار.

وليس علاقة لها خاصية تعدد.

ووالحل يمكن أن يكون نسخ مجموعة. تكرار عبر نسخة وإزالة عناصر من مجموعة الأصلي.

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