ConcurrentModificationException



  • Ohh man ich bin echt am Verzweifeln: Ich schreibe ein Programm in dem ich keine Threads verwende. Trotzdem bekomme ich an folgender Stelle eine java.util.ConcurrentModificationException, die laut Referenz nur bei Threads auftreten kann:

    for (Element e : ems) {// <-- exception
     // ...
    }
    

    Exception:

    java.util.ConcurrentModificationException
      at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:449)
      at java.util.AbstractList$Itr.next(AbstractList.java:420)
      ... (Stellen in meinem Code)
    

    Weiß jemand von euch Rat?
    - Bine



  • Verwendest du das irgednwo in einer GUI-Behandlung (Listener, etc.)? Die erzeugen ganz gern eigene Threads. In dem Fall musst du dann Schutzmechanismen einbauen (Siehe auch synchronized, etc.)

    MfG SideWinder



  • Zeig mal das Innere der for-Schleife. ...ist das selbst auch schon in einer Schleife der Art drin?



  • Mit C++ wäre das nicht passiert.



  • Das Problem wurde bei mir mal durch folgendes hervorgerufen:
    Ich bin über eine Liste enumeriert und habe in dieser Schleife die Liste geändert. Nachdem ich die zu ändernden Elemente in einer seperaten Liste gespeichert habe und die original Liste nach dem durchkämmen aktualisiert habe, trat der Fehler nicht mehr auf.



  • bineAC schrieb:

    die laut Referenz nur bei Threads auftreten kann

    Das ist sicher nicht korrekt. Diese Exception tritt genau dann auf, wenn der Iterator ein anderes Alter als die Collection hat. Der Iterator übernimmt bei der Erstellung das Alter der Collection und die Collection wird älter, wenn man sie strukturell verändert.
    Du tust also die Collection während der Iteration irgendwie ändern, in welchem Thread ist egal.



  • Ihr habt recht (besonders du, Optimizer), ich ändere die ArrayListe, über die ich iteriere in der Schleife. Dann habe ich ich es so probiert

    for (int i = 0; i != ems.size(); ++i) {
     // ...
    }
    

    und bekam nen IndexOutOfBounce, was mich extremst schockiert hat! Die Lösung war das hier:

    int size = ems.size();
    for (int i = 0; i != size; ++i) {
     //...
     ems.remove(i);
     --size;
     //...
    }
    

    Ist vielleicht etwas schneller, als die zu löschenden Elemente in einer Liste zu speichern und später zu löschen.

    Danke an alle, Bine.



  • Also wenn du denn Effekt erzielen willst jedes zweite Element deiner List zu löschen, dann ist deine Variante richtig ansonsten probiers mal mit folgenden.

    while(!ems.isEmpty())
    {
       ems.remove(0);
    }
    

    oder

    ListIterator<Foo> emsIt = ems.listIterator();
    while(it.hasNext())
    {
       it.remove();
    ]
    

    oder gleich

    ems.clear();
    

Anmelden zum Antworten