ConcurrentModificationException uppstår när ett objekt försöks ändras samtidigt när det inte är tillåtet. Detta undantag kommer vanligtvis när man arbetar med Java Collection klasser .
Till exempel - Det är inte tillåtet för en tråd att ändra en samling när någon annan tråd itererar över den. Detta beror på att resultatet av iterationen blir odefinierat med den. Vissa implementeringar av Iterator-klassen kastar detta undantag, inklusive alla de generella implementeringar av Iterator som tillhandahålls av JRE. Iteratorer som gör detta kallas misslyckas snabbt eftersom de kastar undantaget snabbt så fort de stöter på en sådan situation snarare än att möta samlingens obestämda beteende någon gång i framtiden.
8 till 1 multiplexor
Notera:Det är inte obligatoriskt att detta undantag kommer att kastas endast när någon annan tråd försöker ändra ett samlingsobjekt. Det kan också hända om en enskild tråd har anropat några metoder som försöker bryta mot objektets kontrakt. Detta kan hända när en tråd försöker ändra samlingsobjektet medan det upprepas av vissafelsnabb iterator, kommer iteratorn att kasta undantaget.
Exempel
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:
Detta meddelande säger att undantaget kastas när nästa metod anropas eftersom iteratorn itererar listan och vi gör ändringar i den samtidigt. Men om vi gör ändringar i hashmap som anges nedan, kommer det inte att skapa något sådant undantag eftersom storleken på hashmap inte kommer att ändras.
Till exempel-
stad i uas
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
Det här exemplet fungerar helt bra eftersom medan iteratorn itererar över kartan så ändras inte storleken på kartan. Endast kartan uppdateras i om uttalande .
Konstruktörer av ConcurrentModificationException
Det finns 4 typer av konstruktörer av ConcurrentModificationException -
mvc java
- public ConcurrentModificationException() -
Detta skapar ett ConcurrentModificationException utan parametrar. - public ConcurrentModificationException(String message)
Detta skapar ett ConcurrentModificationException med ett detaljerat meddelande som anger undantaget. - public ConcurrentModificationException(Throwable cause)
Detta skapar ett ConcurrentModificationException med en orsak och ett meddelande som är (cause==null?null:cause.toString()). Orsaken hämtas senare av Throwable.getCause(). - public ConcurrentModificationException(Strängmeddelande, Throwable cause)
Detta skapar ett ConcurrentModificationException med ett detaljerat meddelande och en orsak. (cause==null?null:cause.toString()). Meddelandet hämtas senare av Throwable.getMessage() och orsaken hämtas senare av Throwable.getCause().
Hur undviker man ConcurrentModificationException i en flertrådig miljö?
För att undvika ConcurrentModificationException i en flertrådig miljö kan vi följa följande sätt-
- Istället för att iterera över samlingsklassen kan vi iterera över arrayen. På så sätt kan vi fungera mycket bra med små listor, men detta kommer att försämra prestandan om arraystorleken är mycket stor.
- Ett annat sätt kan vara att låsa listan genom att lägga den i det synkroniserade blocket. Detta är inte ett effektivt tillvägagångssätt eftersom det enda syftet med att använda multi-threading avstår från detta.
- JDK 1.5 eller högre tillhandahåller klasserna ConcurrentHashMap och CopyOnWriteArrayList. Dessa klasser hjälper oss att undvika samtidiga modifieringsundantag.
Hur undviker man ConcurrentModificationException i en entrådig miljö?
Genom att använda iterators remove()-funktion kan du ta bort ett objekt från ett underliggande samlingsobjekt.