logo

ConcurrentModificationException в Java

Изключението ConcurrentModificationException възниква, когато обект се опитва да бъде модифициран едновременно, когато това не е допустимо. Това изключение обикновено идва, когато човек работи с Java Collection класове .

Например - Не е позволено за нишка да променя колекция, когато друга нишка итерира върху нея. Това е така, защото резултатът от повторението става недефиниран с него. Някои реализации на класа Iterator хвърлят това изключение, включително всички онези реализации на Iterator с общо предназначение, които се предоставят от JRE. Итераторите, които правят това, се наричат отказоустойчив тъй като те хвърлят изключението бързо, веднага щом се сблъскат с такава ситуация, вместо да се сблъскат с неопределено поведение на колекцията по всяко време в бъдеще.

Powershell администратор

Забележка:Не е задължително това изключение да бъде хвърлено само когато друга нишка се опита да промени обект на колекция. Това може да се случи и ако една нишка има извикани методи, които се опитват да нарушат договора на обекта. Това може да се случи, когато нишка се опитва да модифицира обекта Collection, докато се повтаря от някоиfail-fast итератор, итераторът ще хвърли изключението.

Пример

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

Изход:

ConcurrentModificationException в Java

Това съобщение казва, че изключението се хвърля, когато се извика следващият метод, тъй като итераторът итерира списъка и ние правим модификации в него едновременно. Но ако направим модификации в hashmap, както е дадено по-долу, тогава това няма да хвърли такова изключение, тъй като размерът на hashmap няма да се промени.

Например-

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

Изход:

команда във възел js
 Map Value:1 Map Value:2 Map Value:3 

Този пример работи напълно добре, тъй като докато итераторът итерира върху картата, размерът на картата не се променя. Само картата се актуализира в оператор if .

Конструктори на ConcurrentModificationException

Има 4 вида конструктори на ConcurrentModificationException -

умножение на матрица в c
  1. public ConcurrentModificationException() -
    Това създава изключение ConcurrentModificationException без параметри.
  2. public ConcurrentModificationException(Съобщение от низ)
    Това създава ConcurrentModificationException с подробно съобщение, посочващо изключението.
  3. публичен ConcurrentModificationException (възможна причина)
    Това създава изключение ConcurrentModificationException с причина и съобщение, което е (cause==null?null:cause.toString()). Причината по-късно се извлича от Throwable.getCause().
  4. public ConcurrentModificationException(Съобщение от низ, причина за хвърляне)
    Това създава ConcurrentModificationException с подробно съобщение и причина. (cause==null?null:cause.toString()). Съобщението по-късно се извлича от Throwable.getMessage(), а причината по-късно се извлича от Throwable.getCause().

Как да избегнем ConcurrentModificationException в многонишкова среда?

За да избегнем ConcurrentModificationException в многонишкова среда, можем да следваме следните начини-

  1. Вместо да итерираме в класа на колекцията, можем да итерираме в масива. По този начин можем да работим много добре със списъци с малък размер, но това ще намали производителността, ако размерът на масива е много голям.
  2. Друг начин може да бъде заключване на списъка чрез поставянето му в синхронизирания блок. Това не е ефективен подход, тъй като единствената цел на използването на многопоточност се отказва от това.
  3. JDK 1.5 или по-нова версия предоставя класове ConcurrentHashMap и CopyOnWriteArrayList. Тези класове ни помагат да избегнем изключение за едновременна модификация.

Как да избегнем ConcurrentModificationException в еднонишкова среда?

Като използвате функцията за премахване() на итератора, можете да премахнете обект от основен обект на колекция.