java.util.ConcurrentModificationException in Non Multithreaded-Programm
-
08-07-2019 - |
Frage
Hey SO Gurus im ein Heck eines Auftrags mit diesem Code mit
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());
}
Als ich betreibe mein Programm zum ersten Mal versucht er den Code trifft es diesen Fehler zu laufen
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)
um ein bisschen glotzte Nachdem dies einen Fehler zu sein scheint, die normalerweise mit einem Gewinde passiert, warum sie versuchen, Zugriff auf die gleiche Ressource gleichzeitig, aber das ist, was immer du mich im überhaupt nicht Multithreading in diesem System.
Kann mir jemand erklären, warum dies geschieht, oder denken Sie an einen Hack zu umgehen, es
Vielen Dank ^ _ ^
Lösung
Sie können den zugrunde liegenden Collection
der Iterator
ändern (die in der for-each
Schleife verborgen ist).
Der richtige Weg, dies zu tun ist:
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();
}
}
Andere Tipps
Sie können nicht die for each
Schleife verwenden, wenn Sie die Dinge aus der Sammlung entfernen.
Sie haben eine Iterator
zu verwenden und die aktuelle Element Anruf Iterator.remove
zu entfernen.
Ansonsten ist die zugrunde liegende Iterator, dass die für-jede Schleife hinter den Kulissen für Sie erstellt nicht versteht, wie die Sammlung kommt es los ist durch verändert sich, sagt man, dass es geändert wird, während Sie es durchlaufen.
Sie haben einen Iterator über Bevölkerung für Schleife unter einem versteckten bekommen. Sie sind ein Element aus Bevölkerung in der Mitte der Iterator Arbeits entfernen. Iterator kann nicht nicht mehr arbeiten, weil Sie die Sammlung in der Mitte davon geändert Iterieren.
Es ist nicht im Zusammenhang mit Multithreading.
kann eine Abhilfe eine Sammlung kopieren sein. Iterieren der Kopie und entfernen Sie Elemente aus der ursprünglichen Sammlung.
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());
}