logo

ConcurrentModificationException în Java

Excepția ConcurrentModificationException apare atunci când un obiect este încercat să fie modificat concomitent când nu este permis. Această excepție vine de obicei atunci când cineva lucrează cu Clasele Java Collection .

De exemplu - Nu este permis ca un fir să modifice o colecție atunci când un alt fir iterează peste ea. Acest lucru se datorează faptului că rezultatul iterației devine nedefinit cu acesta. O anumită implementare a clasei Iterator aruncă această excepție, inclusiv toate acele implementări de uz general ale Iterator care sunt furnizate de JRE. Iteratorii care fac acest lucru se numesc eșuează-rapid deoarece ei aruncă excepția rapid de îndată ce se confruntă cu o astfel de situație, mai degrabă decât să se confrunte cu un comportament nedeterminat al colecției oricând în viitor.

r în limbajul c

Notă:Nu este obligatoriu ca această excepție să fie aruncată numai atunci când un alt fir încearcă să modifice un obiect Collection. Se poate întâmpla și dacă un singur thread are unele metode numite care încearcă să încalce contractul obiectului. Acest lucru se poate întâmpla atunci când un fir încearcă să modifice obiectul Colecție în timp ce este repetat de uniiiterator rapid eșuat, iteratorul va arunca excepția.

Exemplu

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

Ieșire:

ConcurrentModificationException în Java

Acest mesaj spune că excepția este aruncată atunci când următoarea metodă este apelată, deoarece iteratorul repetă lista și facem modificări în ea simultan. Dar dacă facem modificări în hashmap ca cele prezentate mai jos, atunci nu va arunca nicio excepție, deoarece dimensiunea hashmap-ului nu se va schimba.

comanda autocad stretch

De exemplu-

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

Ieșire:

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

Acest exemplu funcționează perfect, deoarece în timp ce iteratorul iterează peste hartă, dimensiunea hărții nu se schimbă. Doar harta este actualizată în declarația dacă .

Constructorii ConcurrentModificationException

Există 4 tipuri de constructori ai ConcurrentModificationException -

șir ca matrice
  1. public ConcurrentModificationException() -
    Aceasta creează o excepție ConcurrentModificationException fără parametri.
  2. public ConcurrentModificationException (mesaj șir)
    Aceasta creează o excepție ConcurrentModificationException cu un mesaj detaliat care specifică excepția.
  3. public ConcurrentModificationException (cauza care poate fi aruncată)
    Aceasta creează o excepție ConcurrentModificationException cu o cauză și un mesaj care este (cause==null?null:cause.toString()). Cauza este preluată ulterior de Throwable.getCause().
  4. public ConcurrentModificationException (mesaj șir, cauză care poate fi aruncată)
    Aceasta creează o excepție ConcurrentModificationException cu un mesaj detaliat și o cauză. (cauza==null?null:cause.toString()). Mesajul este preluat ulterior de Throwable.getMessage() și cauza este preluat ulterior de Throwable.getCause().

Cum să evitați ConcurrentModificationException într-un mediu cu mai multe fire?

Pentru a evita ConcurrentModificationException într-un mediu cu mai multe fire, putem urma următoarele moduri:

  1. În loc să iterăm peste clasa de colecție, putem itera peste matrice. În acest fel, putem lucra foarte bine cu liste de dimensiuni mici, dar acest lucru va reduce performanța dacă dimensiunea matricei este foarte mare.
  2. O altă modalitate poate fi blocarea listei prin introducerea acesteia în blocul sincronizat. Aceasta nu este o abordare eficientă, deoarece singurul scop al utilizării multi-threading-ului este renunțat la aceasta.
  3. JDK 1.5 sau o versiune ulterioară oferă clasele ConcurrentHashMap și CopyOnWriteArrayList. Aceste clase ne ajută să evităm excepția modificărilor concurente.

Cum să evitați ConcurrentModificationException într-un mediu cu un singur thread?

Folosind funcția remove() a iteratorului, puteți elimina un obiect dintr-un obiect de colecție subiacent.