logo

ConcurrentModificationException v Javi

Izjema ConcurrentModificationException se pojavi, ko se predmet poskuša sočasno spremeniti, ko to ni dovoljeno. Do te izjeme običajno pride, ko nekdo dela z Razredi zbirke Java .

Na primer - Niti ni dovoljeno spreminjati zbirke, ko neka druga nit ponavlja po njej. To je zato, ker rezultat ponovitve z njim postane nedefiniran. Nekatere izvedbe razreda Iterator vržejo to izjemo, vključno z vsemi splošnimi implementacijami Iteratorja, ki jih ponuja JRE. Iteratorji, ki to počnejo, se imenujejo fail-fast saj izjemo hitro vržejo takoj, ko naletijo na takšno situacijo, namesto da bi se kadar koli v prihodnosti soočili z nedoločenim vedenjem zbirke.

ostri kot

Opomba:Ni obvezno, da bo ta izjema vržena le, ko bo kakšna druga nit poskušala spremeniti objekt zbirke. Lahko se zgodi tudi, če ima posamezna nit klicane metode, ki poskušajo kršiti pogodbo objekta. To se lahko zgodi, ko poskuša nit spremeniti objekt zbirke, medtem ko ga nekateri ponavljajofail-fast iterator, bo iterator vrgel izjemo.

Primer

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

Izhod:

ConcurrentModificationException v Javi

To sporočilo pravi, da se izjema sproži, ko se pokliče naslednja metoda, ko iterator ponavlja seznam in hkrati izvajamo spremembe na njem. Toda če naredimo spremembe v hashmapu, kot je navedeno spodaj, potem to ne bo povzročilo nobene take izjeme, saj se velikost hashmapa ne bo spremenila.

Na primer-

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

Izhod:

oblikovanje baze podatkov v dbms
 Map Value:1 Map Value:2 Map Value:3 

Ta primer deluje popolnoma dobro, saj se velikost zemljevida ne spreminja, medtem ko iterator ponavlja po zemljevidu. Samo zemljevid se posodablja v izjava if .

Konstruktorji ConcurrentModificationException

Obstajajo 4 vrste konstruktorjev ConcurrentModificationException -

pretvori nfa v dfa
  1. public ConcurrentModificationException() -
    To ustvari izjemo ConcurrentModificationException brez parametrov.
  2. public ConcurrentModificationException(String message)
    To ustvari izjemo ConcurrentModificationException s podrobnim sporočilom, ki določa izjemo.
  3. javna ConcurrentModificationException(Throwable vzrok)
    To ustvari izjemo ConcurrentModificationException z vzrokom in sporočilom, ki je (cause==null?null:cause.toString()). Vzrok pozneje pridobi Throwable.getCause().
  4. public ConcurrentModificationException(String message, Throwable cause)
    To ustvari izjemo ConcurrentModificationException s podrobnim sporočilom in vzrokom. (cause==null?null:cause.toString()). Sporočilo pozneje pridobi Throwable.getMessage(), vzrok pa pozneje pridobi Throwable.getCause().

Kako se izogniti ConcurrentModificationException v večnitnem okolju?

Da bi se izognili izjemi ConcurrentModificationException v večnitnem okolju, lahko sledimo naslednjim načinom:

  1. Namesto ponavljanja po razredu zbirke lahko ponovimo po matriki. Na ta način lahko zelo dobro delamo s seznami majhne velikosti, vendar bo to zmanjšalo zmogljivost, če je velikost polja zelo velika.
  2. Drug način je lahko zaklepanje seznama tako, da ga postavite v sinhronizirani blok. To ni učinkovit pristop, saj je s tem opuščen edini namen uporabe večnitnosti.
  3. JDK 1.5 ali novejši ponuja razrede ConcurrentHashMap in CopyOnWriteArrayList. Ti razredi nam pomagajo, da se izognemo izjemi sočasnih sprememb.

Kako se izogniti ConcurrentModificationException v okolju z eno nitjo?

Z uporabo iteratorjeve funkcije remove() lahko odstranite predmet iz osnovnega predmeta zbirke.