logo

ConcurrentModificationException in Java

La ConcurrentModificationException si verifica quando si tenta di modificare contemporaneamente un oggetto quando non è consentito. Questa eccezione di solito arriva quando si lavora con Classi di raccolta Java .

Per esempio - Non è consentito a un thread modificare una raccolta mentre qualche altro thread sta eseguendo un'iterazione su di essa. Questo perché con essa il risultato dell'iterazione diventa indefinito. Alcune implementazioni della classe Iterator generano questa eccezione, incluse tutte quelle implementazioni di uso generale di Iterator fornite da JRE. Gli iteratori che fanno questo vengono chiamati fallire velocemente poiché lanciano rapidamente l'eccezione non appena incontrano tale situazione piuttosto che affrontare un comportamento indeterminato della raccolta in qualsiasi momento in futuro.

r in linguaggio c

Nota:Non è obbligatorio che questa eccezione venga lanciata solo quando qualche altro thread tenta di modificare un oggetto Collection. Può anche succedere se un singolo thread ha chiamati alcuni metodi che tentano di violare il contratto dell'oggetto. Ciò può verificarsi quando un thread tenta di modificare l'oggetto Collection mentre viene ripetuto da alcuniiteratore fail-fast, l'iteratore genererà l'eccezione.

Esempio

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

Produzione:

ConcurrentModificationException in Java

Questo messaggio dice che l'eccezione viene generata quando viene chiamato il metodo successivo mentre l'iteratore sta ripetendo l'elenco e stiamo apportando modifiche allo stesso simultaneamente. Ma se apportiamo modifiche all'hashmap come indicato di seguito, non verrà generata alcuna eccezione di questo tipo poiché la dimensione dell'hashmap non cambierà.

Per esempio-

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

Produzione:

velocità di trasmissione in arduino
 Map Value:1 Map Value:2 Map Value:3 

Questo esempio funziona perfettamente poiché mentre l'iteratore esegue l'iterazione sulla mappa, la dimensione della mappa non cambia. Solo la mappa è in fase di aggiornamento nel se dichiarazione .

Costruttori di ConcurrentModificationException

Esistono 4 tipi di costruttori di ConcurrentModificationException:

jpulsante
  1. public ConcurrentModificationException() -
    Questo crea una ConcurrentModificationException senza parametri.
  2. public ConcurrentModificationException(Messaggio String)
    Ciò crea una ConcurrentModificationException con un messaggio dettagliato che specifica l'eccezione.
  3. public ConcurrentModificationException(causa lanciabile)
    Questo crea una ConcurrentModificationException con una causa e un messaggio che è (cause==null?null:cause.toString()). La causa viene successivamente recuperata da Throwable.getCause().
  4. public ConcurrentModificationException(Messaggio stringa, causa lanciabile)
    Ciò crea una ConcurrentModificationException con un messaggio dettagliato e una causa. (causa==null?null:causa.toString()). Il messaggio viene successivamente recuperato da Throwable.getMessage() e la causa viene successivamente recuperata da Throwable.getCause().

Come evitare ConcurrentModificationException in un ambiente multi-thread?

Per evitare ConcurrentModificationException in un ambiente multi-thread, possiamo seguire i seguenti modi:

  1. Invece di scorrere la classe della raccolta, possiamo scorrere l'array. In questo modo possiamo lavorare molto bene con elenchi di piccole dimensioni, ma ciò ridurrà le prestazioni se la dimensione dell'array è molto grande.
  2. Un altro modo può bloccare l'elenco inserendolo nel blocco sincronizzato. Questo non è un approccio efficace in quanto l'unico scopo dell'utilizzo del multi-threading viene abbandonato.
  3. JDK 1.5 o versioni successive fornisce le classi ConcurrentHashMap e CopyOnWriteArrayList. Queste classi ci aiutano a evitare eccezioni di modifica simultanee.

Come evitare ConcurrentModificationException in un ambiente a thread singolo?

Utilizzando la funzione Remove() dell'iteratore, è possibile rimuovere un oggetto da un oggetto di raccolta sottostante.