logo

Wyjątek ConcurrentModificationException w Javie

Wyjątek ConcurrentModificationException występuje, gdy próbuje się jednocześnie modyfikować obiekt, gdy jest to niedozwolone. Ten wyjątek zwykle pojawia się, gdy ktoś pracuje Klasy kolekcji Java .

Na przykład - Niedozwolone jest, aby wątek modyfikował kolekcję, gdy iteruje po niej jakiś inny wątek. Dzieje się tak, ponieważ wynik iteracji staje się z nim niezdefiniowany. Niektóre implementacje klasy Iterator zgłaszają ten wyjątek, w tym wszystkie implementacje Iteratora ogólnego przeznaczenia, które są dostarczane przez środowisko JRE. Iteratory, które to robią, nazywane są bezawaryjny ponieważ szybko zgłaszają wyjątek, gdy tylko napotkają taką sytuację, zamiast stawić czoła nieokreślonemu zachowaniu kolekcji w dowolnym momencie w przyszłości.

przykłady automatów dfa

Notatka:Nie jest obowiązkowe, aby ten wyjątek był zgłaszany tylko wtedy, gdy jakiś inny wątek próbuje zmodyfikować obiekt Collection. Może się to również zdarzyć, jeśli w pojedynczym wątku wywołane zostaną metody, które próbują naruszyć umowę obiektu. Może się to zdarzyć, gdy wątek próbuje zmodyfikować obiekt Collection, gdy jest on przez niektórych iterowanyiterator niezawodny, iterator zgłosi wyjątek.

Przykład

 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); } } } 

Wyjście:

Wyjątek ConcurrentModificationException w Javie

Komunikat ten informuje, że wyjątek jest zgłaszany przy wywołaniu kolejnej metody, gdy iterator iteruje listę i jednocześnie wprowadzamy w niej modyfikacje. Ale jeśli dokonamy modyfikacji w mapie skrótu, jak podano poniżej, nie wygeneruje to żadnego wyjątku, ponieważ rozmiar mapy skrótu nie ulegnie zmianie.

Na przykład-

 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); } } } } 

Wyjście:

if else instrukcje Java
 Map Value:1 Map Value:2 Map Value:3 

Ten przykład działa całkowicie dobrze, ponieważ gdy iterator iteruje po mapie, rozmiar mapy się nie zmienia. Tylko mapa jest aktualizowana w jeśli stwierdzenie .

Konstruktorzy ConcurrentModificationException

Istnieją 4 typy konstruktorów ConcurrentModificationException -

śpij dla javascript
  1. publiczny wyjątek ConcurrentModificationException() -
    Tworzy to wyjątek ConcurrentModificationException bez parametrów.
  2. publiczny wyjątek ConcurrentModificationException (wiadomość typu String)
    Spowoduje to utworzenie wyjątku ConcurrentModificationException ze szczegółowym komunikatem określającym wyjątek.
  3. public ConcurrentModificationException (przyczyna, którą można zgłosić)
    Tworzy to wyjątek ConcurrentModificationException z przyczyną i komunikatem (przyczyna==null?null:przyczyna.toString()). Przyczyna jest później pobierana przez metodę Throwable.getCause().
  4. public ConcurrentModificationException (wiadomość typu String, przyczyna, którą można zgłosić)
    Spowoduje to utworzenie wyjątku ConcurrentModificationException ze szczegółowym komunikatem i przyczyną. (przyczyna==null?null:przyczyna.toString()). Komunikat jest później pobierany przez Throwable.getMessage(), a przyczyna jest później pobierana przez Throwable.getCause().

Jak uniknąć wyjątku ConcurrentModificationException w środowisku wielowątkowym?

Aby uniknąć wyjątku ConcurrentModificationException w środowisku wielowątkowym, możemy zastosować następujące sposoby:

  1. Zamiast iterować po klasie kolekcji, możemy iterować po tablicy. W ten sposób możemy bardzo dobrze pracować z listami o małych rozmiarach, ale spowoduje to zmniejszenie wydajności, jeśli rozmiar tablicy jest bardzo duży.
  2. Innym sposobem może być zablokowanie listy poprzez umieszczenie jej w bloku synchronizowanym. Nie jest to skuteczne podejście, ponieważ w ten sposób rezygnuje się z jedynego celu stosowania wielowątkowości.
  3. JDK 1.5 lub nowszy udostępnia klasy ConcurrentHashMap i CopyOnWriteArrayList. Klasy te pomagają nam unikać wyjątków związanych z równoczesną modyfikacją.

Jak uniknąć wyjątku ConcurrentModificationException w środowisku jednowątkowym?

Używając funkcji usuwania() iteratora, można usunąć obiekt z bazowego obiektu kolekcji.