logo

ConcurrentModificationException in Java

Die ConcurrentModificationException tritt auf, wenn versucht wird, ein Objekt gleichzeitig zu ändern, obwohl dies nicht zulässig ist. Diese Ausnahme tritt normalerweise auf, wenn mit gearbeitet wird Java Collection-Klassen .

Zum Beispiel – Es ist einem Thread nicht gestattet, eine Sammlung zu ändern, während ein anderer Thread darüber iteriert. Dies liegt daran, dass das Ergebnis der Iteration damit undefiniert wird. Einige Implementierungen der Iterator-Klasse lösen diese Ausnahme aus, einschließlich aller allgemeinen Implementierungen von Iterator, die von der JRE bereitgestellt werden. Iteratoren, die dies tun, werden aufgerufen ausfallsicher da sie die Ausnahme schnell auslösen, sobald sie auf eine solche Situation stoßen, anstatt in der Zukunft mit einem unbestimmten Verhalten der Sammlung konfrontiert zu werden.

Nginx-Variablen

Notiz:Es ist nicht zwingend erforderlich, dass diese Ausnahme nur dann ausgelöst wird, wenn ein anderer Thread versucht, ein Collection-Objekt zu ändern. Es kann auch passieren, wenn in einem einzelnen Thread einige Methoden aufgerufen werden, die versuchen, den Vertrag des Objekts zu verletzen. Dies kann passieren, wenn ein Thread versucht, das Collection-Objekt zu ändern, während es von einigen iteriert wirdausfallsicherer Iterator, löst der Iterator die Ausnahme aus.

Beispiel

 import java.awt.List; import java.util.*; public class Concurrentmodificationexception { public static void main(String[] args) { ArrayList list = new ArrayList(); list.add(1); list.add(2); list.add(3); list.add(4); list.add(5); Iterator it = list.iterator(); while (it.hasNext()) { Integer value = it.next(); System.out.println('List Value:' + value); if (value.equals(3)) list.remove(value); } } } 

Ausgabe:

ConcurrentModificationException in Java

Diese Meldung besagt, dass die Ausnahme ausgelöst wird, wenn die nächste Methode aufgerufen wird, während der Iterator die Liste iteriert und wir gleichzeitig Änderungen daran vornehmen. Wenn wir jedoch wie unten angegeben Änderungen an der Hashmap vornehmen, wird keine solche Ausnahme ausgelöst, da sich die Größe der Hashmap nicht ändert.

Python-Druck auf 2 Dezimalstellen

Zum Beispiel-

 import java.awt.List; import java.util.*; public class concurrentmodificationexception { public static void main(String[] args) { HashMap map = new HashMap(); map.put(1, 1); map.put(2, 2); map.put(3,3); Iterator it = map.keySet().iterator(); while(it.hasNext()) { Integer key = it.next(); System.out.println('Map Value:' + map.get(key)); if (key.equals(2)) { map.put(1, 4); } } } } 

Ausgabe:

 Map Value:1 Map Value:2 Map Value:3 

Dieses Beispiel funktioniert völlig einwandfrei, da sich die Größe der Karte nicht ändert, während der Iterator über die Karte iteriert. Lediglich die Karte wird im aktualisiert if-Anweisung .

Konstruktoren von ConcurrentModificationException

Es gibt 4 Arten von Konstruktoren für ConcurrentModificationException:

Bullen gegen Ochsen
  1. öffentliche ConcurrentModificationException() -
    Dadurch wird eine ConcurrentModificationException ohne Parameter erstellt.
  2. öffentliche ConcurrentModificationException(String-Nachricht)
    Dadurch wird eine ConcurrentModificationException mit einer detaillierten Meldung erstellt, die die Ausnahme angibt.
  3. öffentliche ConcurrentModificationException (auslösbare Ursache)
    Dadurch wird eine ConcurrentModificationException mit einer Ursache und einer Meldung erstellt, die (cause==null?null:cause.toString()) lautet. Die Ursache wird später von Throwable.getCause() abgerufen.
  4. öffentliche ConcurrentModificationException(String-Nachricht, auslösbare Ursache)
    Dadurch wird eine ConcurrentModificationException mit einer detaillierten Meldung und einer Ursache erstellt. (cause==null?null:cause.toString()). Die Nachricht wird später von Throwable.getMessage() abgerufen und die Ursache wird später von Throwable.getCause() abgerufen.

Wie vermeide ich ConcurrentModificationException in einer Multithread-Umgebung?

Um die ConcurrentModificationException in einer Multithread-Umgebung zu vermeiden, können wir die folgenden Möglichkeiten befolgen:

  1. Anstatt über die Sammlungsklasse zu iterieren, können wir über das Array iterieren. Auf diese Weise können wir sehr gut mit kleinen Listen arbeiten, allerdings wird dadurch die Leistung beeinträchtigt, wenn die Array-Größe sehr groß ist.
  2. Eine andere Möglichkeit besteht darin, die Liste zu sperren, indem Sie sie in den synchronisierten Block einfügen. Dies ist kein effektiver Ansatz, da dadurch der alleinige Zweck der Verwendung von Multithreading aufgegeben wird.
  3. JDK 1.5 oder höher bietet die Klassen ConcurrentHashMap und CopyOnWriteArrayList. Diese Klassen helfen uns, Ausnahmen bei gleichzeitiger Änderung zu vermeiden.

Wie vermeide ich ConcurrentModificationException in einer Single-Threaded-Umgebung?

Mithilfe der Funktion „remove()“ des Iterators können Sie ein Objekt aus einem zugrunde liegenden Sammlungsobjekt entfernen.