A ConcurrentModificationException akkor fordul elő, ha egy objektumot egyidejűleg próbálnak módosítani, amikor az nem megengedett. Ez a kivétel általában akkor következik be, amikor az ember dolgozik Java Collection osztályok .
Például - Nem megengedett, hogy egy szál módosítson egy gyűjteményt, amikor egy másik szál iterál rajta. Ennek az az oka, hogy az iteráció eredménye definiálatlan lesz vele. Az Iterator osztály egyes megvalósításai ezt a kivételt jelentik, beleértve az Iterator összes olyan általános célú megvalósítását, amelyet a JRE biztosít. Az ilyen iterátorokat hívják sikertelen mivel gyorsan kidobják a kivételt, amint ilyen helyzetbe ütköznek, nem pedig a jövőben a gyűjtemény meghatározatlan viselkedésével kell szembenézniük.
karakterlánc a jsonobjecthez
Jegyzet:Nem kötelező, hogy ez a kivétel csak akkor kerüljön megadásra, ha egy másik szál megpróbálja módosítani a Collection objektumot. Ez akkor is megtörténhet, ha egyetlen szálnak vannak olyan meghívott metódusai, amelyek megpróbálják megsérteni az objektum szerződését. Ez akkor fordulhat elő, amikor egy szál megpróbálja módosítani a Collection objektumot, miközben egyesek iteráljákhibagyors iterátor, az iterátor kivételt dob.
Példa
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); } } }
Kimenet:
Ez az üzenet azt mondja, hogy a kivétel a következő metódus meghívásakor jelenik meg, mivel az iterátor iterálja a listát, és egyidejűleg módosításokat hajtunk végre rajta. De ha az alábbiak szerint módosítjuk a hashmap-et, akkor az nem fog kivételt tenni, mivel a hashmap mérete nem változik.
kruskal algoritmus
Például-
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); } } } }
Kimenet:
Map Value:1 Map Value:2 Map Value:3
Ez a példa teljesen jól működik, mivel amíg az iterátor a térképen iterál, a térkép mérete nem változik. Csak a térkép frissül a ha nyilatkozat .
A ConcurrentModificationException konstruktorai
A ConcurrentModificationException konstruktorának 4 típusa létezik -
css változó képméret
- public ConcurrentModificationException() -
Ezzel egy ConcurrentModificationExceptiont hoz létre paraméterek nélkül. - nyilvános ConcurrentModificationException(karakterlánc üzenet)
Ez létrehoz egy ConcurrentModificationException-t a kivételt meghatározó részletes üzenettel. - nyilvános ConcurrentModificationException (feldobható ok)
Ez egy ConcurrentModificationException-t hoz létre egy okkal és egy üzenettel, amely (cause==null?null:cause.toString()). Az okot később a Throwable.getCause() keresi meg. - nyilvános ConcurrentModificationException (karakterlánc üzenet, dobható ok)
Ez egy ConcurrentModificationException-t hoz létre részletes üzenettel és okokkal. (cause==null?null:cause.toString()). Az üzenetet később a Throwable.getMessage() kéri le, az okot pedig később a Throwable.getCause().
Hogyan kerülhető el a ConcurrentModificationException egy többszálú környezetben?
A ConcurrentModificationException elkerülése érdekében többszálú környezetben a következő módokat követhetjük:
- Ahelyett, hogy a gyűjteményosztályon át iterálnánk, iterálhatunk a tömbön keresztül. Ily módon nagyon jól tudunk dolgozni kis méretű listákkal, de ez rontja a teljesítményt, ha a tömb mérete nagyon nagy.
- Egy másik módszer lehet a lista zárolása a szinkronizált blokkba való behelyezéssel. Ez nem hatékony megközelítés, mivel ez a többszálas használat egyetlen célját feladja.
- A JDK 1.5 vagy újabb verziója tartalmazza a ConcurrentHashMap és CopyOnWriteArrayList osztályokat. Ezek az osztályok segítenek elkerülni az egyidejű módosítási kivételeket.
Hogyan kerülhető el a ConcurrentModificationException egyszálú környezetben?
Az iterátor remove() függvényének használatával eltávolíthat egy objektumot egy mögöttes gyűjteményobjektumból.