Ich schreibe einen Prozess, der sich in einer Listenschleife in Java (bei der Arbeit) ständig vergrößert (Liste). "

I "Willst du es versuchen?"

List<String> list = new ArrayList<>(Arrays.asList("foo", "hoo", "hoge"));
for (String str : list) {
    list.add(str);
}
System.out.println(list);

//Ausnahme aufgetreten
// Exception in thread "main" java.util.ConcurrentModificationException
// 	at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1042)
// 	at java.base/java.util.ArrayList$Itr.next(ArrayList.java:996)

I "ConcurrentModificationException?" Ich "__ Wer bist du __" I "Willst du es für jeden versuchen?"

list.stream().forEach(list::add);
System.out.println(list);
// Exception in thread "main" java.util.ConcurrentModificationException
// 	at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1660)
//	at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:658)

Ich "Nein ..." Ich sagte: "Wenn dies der Fall ist, mache ich Siesta die Zeit nach dem Mittagessen, die bereits schläfrig ist." Ich "Oh ..." Teamleiter "sig-kun" Teamleiter "Ich habe Sie am Morgen nach den Ermittlungen gefragt. Haben Sie etwas verstanden?" Ich "Anführer ...!" Ich "(ich habe es nicht getan)" I "(Zur Zeit __ Ich habe das Gefühl, ich mache etwas Arbeit __ Ich habe dir den aktuellen Bildschirm gezeigt, um es zu bekommen)" Ich mag das" Teamleiter "Wie ..." Teamleiter "Diese Ausnahme namens ConcurrentModificationException tritt auf, wenn [__ wenn die Anzahl der Elemente in der ursprünglichen Liste während der iterativen Verarbeitung geändert wird__]." Teamleiter "Der Java-Iterator zeichnet intern auf, wie oft __ seine eigene Struktur mit dem Variablennamen modCount geändert hat, und löst eine Ausnahme aus, wenn bei wiederholter Verarbeitung für diese Anzahl von Änderungen eine Diskrepanz festgestellt wird. Es wird "

Beispiel: Implementierung von ArrayList



//modCount mit add(Anzahl der Änderungen)Ist aktualisiert
public boolean add(E e) {
    modCount++;
    add(e, elementData, size);
    return true;
}

// modCount(Anzahl der Änderungen)Kontrolle von=>Wirf eine Ausnahme aus, wenn eine Lücke besteht
final void checkForComodification() {
    if (modCount != expectedModCount)
        throw new ConcurrentModificationException();
}

//Überprüfen Sie die Anzahl der Änderungen jedes Mal, wenn Sie zur nächsten Schleife wechseln
public E next() {
    checkForComodification();  // modCount(Anzahl der Änderungen)Überprüfung wird durchgeführt
    int i = cursor;
    if (i >= size)
        throw new NoSuchElementException();
    Object[] elementData = ArrayList.this.elementData;
    if (i >= elementData.length)
        throw new ConcurrentModificationException();
    cursor = i + 1;
    return (E) elementData[lastRet = i];
}

Ich "Oh" Ich "Warum machst du dir die Mühe, das zu tun?" Teamleiter "Viele Java-Sammlungen verwenden Failfast" Ich "Failfast?" Teamleiter "Es ist ein Stock, der nicht fällt. Bevor er versagt, löst er eine Ausnahme aus, wenn er eine Gefahr erkennt." Teamleiter "Weil Java grundsätzlich sagt, dass es das Umschreiben der Struktur der Sammlung im Multithreading nicht garantiert." Teamleiter "Dieses Mal war es Single-Threaded, aber ich versuche zuerst, eine Ausnahme auszulösen, damit es in Ordnung ist, wenn es Multi-Threaded ist." Ich "ich verstehe" Ich bin ein vorsichtiger Typ ... " Teamleiter "Wenn Sie die Struktur von außerhalb des Iterators ändern, ist sie übrigens nicht verfügbar, aber Sie können sie auch innerhalb des Iterators verfolgen. __"

Fügen Sie aus dem Iterator hinzu


List<String> list = new ArrayList<>(Arrays.asList("foo", "hoo", "hoge"));
for (ListIterator<String> itr = list.listIterator(); itr.hasNext();) {
    String str = itr.next();
    itr.add(str + "_itr");
}
System.out.println(list);
// [foo, foo_itr, hoo, hoo_itr, hoge, hoge_itr]

Ich "Anführer, __ ich bin nicht in einer Endlosschleife __" I "(Ich möchte spielen, während ich mir das ständig wachsende Array bis zur festgelegten Zeit ansehe ...)" Teamleiter "Weil das von ListIterator.add hinzugefügte Element direkt vor __next des Iterators eingefügt wird." Teamleiter "Wirkt sich nicht auf nachfolgende hasNext () oder next () aus." Ich "(im Ernst)" Teamleiter "Ich würde es lieber bald sagen" Teamleiter "Das __ hat nichts mit Arbeit zu tun " Teamleiter "Haben Sie die Umfrage durchgeführt, nach der Sie gefragt haben?" Ich " (nicht tun) " Teamleiter "Ich verstehe" Teamleiter "Es gibt endlose Jobs, also für Sig-Kun, der vorerst frei zu sein scheint, dies und das diese Woche ..." Ich "Anführer!" Teamleiter "Was" Ich " Ich gehe früh, weil ich die Gefahr gespürt habe " I " Failfast Return Home __" Teamleiter "Arbeit, weil es in Ordnung ist"

Grobe Zusammenfassung: Was ist ConcurrentModificationException?

Recommended Posts

Ich schreibe einen Prozess, der sich in einer Listenschleife in Java (bei der Arbeit) ständig vergrößert (Liste). "
Erstellen Sie eine benannte SkipList in Java, die wie eine nach Redis sortierte Menge aussieht
Ich habe eine Sterling-Sorte geschrieben, die sich wie in Java anfühlt
Implementieren Sie so etwas wie einen Stack in Java
Verarbeiten Sie eine beliebige Anzahl von Fällen in Java List
Eine Bat-Datei, die Java in Windows verwendet
[Java] Führen Sie einen bestimmten Prozess in einem anderen Thread mit Executor Service aus. [Endlosschleife vermeiden]