ConcurrentModificationException opstår, når et objekt forsøges ændret samtidigt, når det ikke er tilladt. Denne undtagelse kommer normalt, når man arbejder med Java Collection klasser .
For eksempel - Det er ikke tilladt for en tråd at ændre en samling, når en anden tråd gentager den. Dette skyldes, at resultatet af iterationen bliver udefineret med det. Nogle implementeringer af Iterator-klassen kaster denne undtagelse, inklusive alle de generelle implementeringer af Iterator, som leveres af JRE. Iteratorer, der gør dette, kaldes fejl-hurtigt da de kaster undtagelsen hurtigt, så snart de støder på en sådan situation i stedet for at stå over for samlingens ubestemte opførsel når som helst i fremtiden.
udvidelsesfil java
Bemærk:Det er ikke obligatorisk, at denne undtagelse kun bliver kastet, når en anden tråd forsøger at ændre et samlingsobjekt. Det kan også ske, hvis en enkelt tråd har nogle metoder kaldet, som forsøger at overtræde objektets kontrakt. Dette kan ske, når en tråd forsøger at ændre samlingsobjektet, mens det gentages af noglefejl-hurtig iterator, vil iteratoren kaste undtagelsen.
Eksempel
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); } } }
Produktion:
Denne meddelelse siger, at undtagelsen kastes, når den næste metode kaldes, da iteratoren itererer listen, og vi foretager ændringer i den samtidigt. Men hvis vi laver ændringer i hashmap som vist nedenfor, vil det ikke give nogen sådan undtagelse, da størrelsen af hashmap ikke vil ændre sig.
For eksempel-
svævende css
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); } } } }
Produktion:
Map Value:1 Map Value:2 Map Value:3
Dette eksempel fungerer helt fint, da mens iteratoren itererer over kortet, ændres størrelsen af kortet ikke. Kun kortet bliver opdateret i hvis erklæring .
Konstruktører af ConcurrentModificationException
Der er 4 typer konstruktører af ConcurrentModificationException -
hvordan opgraderer jeg java
- public ConcurrentModificationException() -
Dette opretter en ConcurrentModificationException uden parametre. - offentlig ConcurrentModificationException(String message)
Dette opretter en ConcurrentModificationException med en detaljeret meddelelse, der specificerer undtagelsen. - offentlig ConcurrentModificationException(Throwable cause)
Dette opretter en ConcurrentModificationException med en årsag og en meddelelse, som er (cause==null?null:cause.toString()). Årsagen hentes senere af Throwable.getCause(). - offentlig ConcurrentModificationException(String message, Throwable cause)
Dette skaber en ConcurrentModificationException med en detaljeret besked og en årsag. (cause==null?null:cause.toString()). Meddelelsen hentes senere af Throwable.getMessage() og årsagen hentes senere af Throwable.getCause().
Hvordan undgår man ConcurrentModificationException i et multi-threaded miljø?
For at undgå ConcurrentModificationException i et multi-threaded miljø kan vi følge følgende måder-
- I stedet for at iterere over samlingsklassen, kan vi iterere over arrayet. På denne måde kan vi arbejde meget godt med små lister, men det vil sænke ydeevnen, hvis array-størrelsen er meget stor.
- En anden måde kan være at låse listen ved at sætte den i den synkroniserede blok. Dette er ikke en effektiv tilgang, da det eneste formål med at bruge multi-threading er opgivet af dette.
- JDK 1.5 eller højere giver klasserne ConcurrentHashMap og CopyOnWriteArrayList. Disse klasser hjælper os med at undgå samtidige modifikationer.
Hvordan undgår man ConcurrentModificationException i et enkelt-trådet miljø?
Ved at bruge iterators remove()-funktion kan du fjerne et objekt fra et underliggende samlingsobjekt.