ConcurrentModificationException

Luk10

Top Contributor
Huhu,

Ich hab ein kleines Programm geschrieben und erhalte folgende Exception:

Exception in thread "Thread-3" java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
at java.util.AbstractList$Itr.next(AbstractList.java:343)
at de.CellSim.Gamepanel.ueberpruefeTeilen(Gamepanel.java:81)
at de.CellSim.Gamepanel.run(Gamepanel.java:55)
at java.lang.Thread.run(Thread.java:619)


Nun meine Frage:

Kann mir jemand spontan sagen was es damit auf sich hat, bzw. wo der Fehler häufig liegt, wenn man sowas bekommt ...

Danke, Luk
 
Die Fehlermeldung selbst sagt ja schon einiges aus, bzw. lies dir mal in den javadoc die Beschreibung dazu durch. Gibt mehrere Möglichkeiten weshalb die Exception auftritt. Das lustige daran ist, dass es nichtmal unbedingt eine Exception sein muss, nur sein könnte, und sie deshalb geworfen wird *g*

Wie gesagt, lies dir die javadoc dazu durch.
 
Ich bekam diese Exception jeweils, wenn mehrere Threads auf eine nicht synchronisierte List zugreifen wollten.

Ein einfacher weg ist die über die Collections eine synchronisierte List zu holen, hier ein Beispiel mit einer ArrayList:
[Java]
List list = Collections.synchronizedList( new ArrayList() );
[/Java]

PS:
Ich hoffe, dass du so dein Problem lösen kannst.
 
Ich bekam diese Exception jeweils, wenn mehrere Threads auf eine nicht synchronisierte List zugreifen wollten.

Ein einfacher weg ist die über die Collections eine synchronisierte List zu holen[…]
Entschuldige, aber das kann nicht stimmen. Sofern es sich um Standard-JRE-Collections handelt, taucht eine ConcurrentModificationException immer nur in Verbindung mit Iterator-Instanzen auf, wenn die Collection während der Iterator-Abarbeitung verändert wurde. Dabei hilft aber eine synchronisierte Collection nur dann etwas, wenn der gesamte Block der Iterator-Abarbeitung in einem Block liegen würde der auf die Collection synchronisiert.

Falls ich hier Unrecht habe, wünsche ich mir einen Beispielquelltext.

Nicht synchronisierte Collections in verschiedenen Threads zu verwenden führt zu ganz anderen Fehlern.

Ebenius
 
Ich glaube ich habe mich nicht klar genug / schlecht ausgedrückt (oder ich habe da wirklich etwas falsch verstanden).

Ich hatte einmal das Problem, dass mehrere Threads eine nicht synchronisierte List verändert (ich habe vorhin leider nur zugreifen geschrieben) haben, so dass neue Elemente hinzugefügt oder gelöscht wurden. In diesem Fall kann tatsächlich eine solche Exception ausgelöst werden, oder liege ich da falsch? (Natürlich kann dies auch ohne mehrere Threads passieren, da muss ich dir recht geben).

Eist nich ein grundsätzliches Problem von Synchronisation... ich habe das Problem einfach einmal wie oben beschrieben gehabt.
 
Entschuldige, aber das kann nicht stimmen. Sofern es sich um Standard-JRE-Collections handelt, taucht eine ConcurrentModificationException immer nur in Verbindung mit Iterator-Instanzen auf, wenn die Collection während der Iterator-Abarbeitung verändert wurde. Dabei hilft aber eine synchronisierte Collection nur dann etwas, wenn der gesamte Block der Iterator-Abarbeitung in einem Block liegen würde der auf die Collection synchronisiert.

Falls ich hier Unrecht habe, wünsche ich mir einen Beispielquelltext.

Nicht synchronisierte Collections in verschiedenen Threads zu verwenden führt zu ganz anderen Fehlern.

Ebenius

this!

Was kann ich denn dagegen tun?
Ich prüfe in einer for-schleife auf einen bestimmten wert von objekten in einer arraylist, und fügen wenn die bedingung erfüllt ist ein Objekt ebendieser arraylist hinzu!

Danke, Luk

Edit:

folgendes kann ich leider nicht verwenden:

Java:
int groesse = meineListe.size();
for (int i = 0; i < groesse; i++) {
  machenIrgendwas();
}

Da ich mit einem Interface arbeite und die Methode nur für Objekte aufrufen will die dieses Interface implementieren:

Java:
public void ueberpruefeTeilen () {
        for (Teilbar teil : Verwalter.getVerwalter().getAlleGrafiken()) {
            teil.teilen();
        }
}
 
Zuletzt bearbeitet:
Ich glaube ich habe mich nicht klar genug / schlecht ausgedrückt (oder ich habe da wirklich etwas falsch verstanden).
Eine ConcurrentModificationException kann durch aus durch Zugriff aus verschiedenen Threads auftauchen. Das bezweifele ich ja gar nicht. Ich möchte den Quelltext sehen, der das Problem allein dadurch behebt, dass die Collection als eine synchronisierte Collection erzeugt wird. Das ist, was meines Erachtens nicht geht.

@Luk: Du kannst Dir ja eine Kopie der Liste erzeugen und über diese Iterieren; zum Beispiel:
Java:
public void ueberpruefeTeilen () {
        final Collection <? extends Teilbar> collection = Verwalter.getVerwalter().getAlleGrafiken();
        for (Teilbar teil : collection.toArray(new Teilbar[collection.size()]) {
            teil.teilen();
        }
}
Ebenius
 
Eine ConcurrentModificationException kann durch aus durch Zugriff aus verschiedenen Threads auftauchen. Das bezweifele ich ja gar nicht. Ich möchte den Quelltext sehen, der das Problem allein dadurch behebt, dass die Collection als eine synchronisierte Collection erzeugt wird. Das ist, was meines Erachtens nicht geht.

@Luk: Du kannst Dir ja eine Kopie der Liste erzeugen und über diese Iterieren; zum Beispiel:

Ebenius

Das funktioniert schonmal beine "phase" lang d.h. in meiner run eine while-schleife durch, dann bekomme ich wieder folgendes:

Exception in thread "AWT-EventQueue-0" java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
at java.util.AbstractList$Itr.next(AbstractList.java:343)
at de.CellSim.Gamepanel.paintComponent(Gamepanel.java:69)
at javax.swing.JComponent.paint(JComponent.java:1017)
at javax.swing.JComponent.paintToOffscreen(JComponent.java:5112)
at javax.swing.BufferStrategyPaintManager.paint(BufferStrategyPaintManager.java:278)
at javax.swing.RepaintManager.paint(RepaintManager.java:1220)
at javax.swing.JComponent._paintImmediately(JComponent.java:5060)
at javax.swing.JComponent.paintImmediately(JComponent.java:4870)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:803)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:714)
at javax.swing.RepaintManager.seqPaintDirtyRegions(RepaintManager.java:694)
at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(SystemEventQueueUtilities.java:125)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

Exception in thread "AWT-EventQueue-0" java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
at java.util.AbstractList$Itr.next(AbstractList.java:343)
at de.CellSim.Gamepanel.paintComponent(Gamepanel.java:69)
at javax.swing.JComponent.paint(JComponent.java:1017)
at javax.swing.JComponent.paintToOffscreen(JComponent.java:5112)
at javax.swing.BufferStrategyPaintManager.paint(BufferStrategyPaintManager.java:278)
at javax.swing.RepaintManager.paint(RepaintManager.java:1220)
at javax.swing.JComponent._paintImmediately(JComponent.java:5060)
at javax.swing.JComponent.paintImmediately(JComponent.java:4870)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:803)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:714)
at javax.swing.RepaintManager.seqPaintDirtyRegions(RepaintManager.java:694)
at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(SystemEventQueueUtilities.java:125)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

Exception in thread "Thread-3" java.lang.ArrayIndexOutOfBoundsException: 0
at de.CellSim.Hefezelle.teilen(Hefezelle.java:29)
at de.CellSim.Gamepanel.ueberpruefeTeilen(Gamepanel.java:85)
at de.CellSim.Gamepanel.run(Gamepanel.java:56)
at java.lang.Thread.run(Thread.java:619)


Das Programm läuft noch weiter bis ich die ArrayLindexOutOfBoundsException bekomme ...
Um die muss ich mal schau, dass ich mich kümmere wenn's nix mit dem Problem hier zu tun hat ...

Nur ist jetzt wieder diese blöde Excepion aufgetaucht ...

Danke, Luk
 
Ich würde alle neu erzeugten (geteilten) in eine neue Liste schreiben.
Pseudopseudocode, habe grad nicht viel Zeit:

while(teilbar)
{
List l=new List();
for(X x:alle)x.tuAlleGeteiltenInNeueListe(l);
alle=l;
}
 
Soll ich diese neue Liste nach der for Schleife der eingentlichen Liste hinzufügen?
Da ich sonst Problem mit meiner drawImage() bekomme?
Weil ich kann ja nicht sagen
Java:
alleGrafiken = neuDazugekommeneGeteilte;

Da gehen mir die vorherigen verloren!

Danke, Luk
 
Die lösung gibt mir schonmal keine ConcurrentModificationException aber ich hab da immernoch die ArrayIndex Exception bevor ich sicher sagen kann das es funktioniert!

Vielen Dank, Luk

Edit:

Hab den Fehler gefunden ... klappt jetzt Einwandfrei!
Danke an alle die mir geholfen haben!

Edit 2:

Die Lösung anhand meines Codebsp:

Java:
    public void ueberpruefeTeilen () {
        ArrayList<Zelle> neueZellen = new ArrayList<Zelle>();
        for (Teilbar teil : Verwalter.getVerwalter().getAlleGrafiken()) {
            teil.teilen(neueZellen);
        }
        Verwalter.getVerwalter().getAlleGrafiken().addAll(neueZellen);
    }

Ich übergebe teilen(...) meine ArrayList zum speichern der neu erzeugten Zellen!
 
Zuletzt bearbeitet:
in (Hefezelle.java:29) willst Du ein Element rausholen, obwohl die Liste leer ist.
Entweder Du machst den Fehler list.get(0) oder etwas anderes - da kann man nur raten.
 

Zurück
Oben