java.util.ConcurrentModificationException في برنامج غير متعددة مؤشرات الترابط
-
08-07-2019 - |
سؤال
ويا 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());
و}