Kolleksiyanı gəzərkən ConcurrentModificationException istisnasını necə qarşısını almaq olar?
sobes.tech Süni İntellekt
AI-dan cavab
İstifadə olunan kolleksiyanı iterasiya edərkən ConcurrentModificationException-dan qaçınmaq üçün aşağıdakı yanaşmalardan istifadə etmək mümkündür:
-
İş parçalarına qarşı təhlükəsiz kolleksiyaların istifadəsi:
java.util.concurrentstandart kolleksiyaların təhlükəsiz alternativlərini təqdim edir. Məsələn:CopyOnWriteArrayListArrayListyerinəCopyOnWriteArraySetHashSetyerinəConcurrentHashMapHashMapyerinə
// CopyOnWriteArrayList ilə nümunə import java.util.concurrent.CopyOnWriteArrayList; import java.util.Iterator; public class ConcurrentCollectionExample { public static void main(String[] args) { CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>(); list.add("A"); list.add("B"); list.add("C"); // Iterator `ConcurrentModificationException` atmayacaq Iterator<String> iterator = list.iterator(); while (iterator.hasNext()) { String element = iterator.next(); System.out.println(element); // Kolleksiyanı dəyişmək təhlükəsizdir if (element.equals("B")) { list.remove(element); } } System.out.println("Nəticə listi: " + list); } } -
Kolleksiyanı kilidləmək:
synchronizedvə yajava.util.concurrent.locksistifadə edərək kolleksiyaya giriş sinxronlaşdırın.// Synchronized blok nümunəsi import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class SynchronizedCollectionExample { public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("A"); list.add("B"); list.add("C"); synchronized (list) { // Kolleksiyanı kilidləyirik Iterator<String> iterator = list.iterator(); while (iterator.hasNext()) { String element = iterator.next(); System.out.println(element); // Burada kolleksiyanı dəyişmək olmaz, əks halda başqa bir iş parçacı giriş edə bilər } } // Kolleksiyanı sinxronizasiya olunmayan halda və ya başqa iş parçacığı ilə dəyişmək // `ConcurrentModificationException`-a səbəb ola bilər } } -
Iterator istifadə edərək elementləri silmək: Əgər elementləri silmək lazımdırsa,
remove()metodundan istifadə edin (əgər kolleksiya dəstəkləyirsə).// Iterator.remove() ilə silmə nümunəsi import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class IteratorRemoveExample { public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("A"); list.add("B"); list.add("C"); Iterator<String> iterator = list.iterator(); while (iterator.hasNext()) { String element = iterator.next(); System.out.println(element); // Iterator vasitəsilə elementin silinməsi təhlükəsizdir if (element.equals("B")) { iterator.remove(); } } System.out.println("Nəticə listi: " + list); } } -
Kolleksiyanın surətinə keçin: Kolleksiyanın surətini yaradın və onun üzərində iterasiya edin. Əsas kolleksiyada edilən dəyişikliklər surətə təsir etməz.
// Surət üzərində iterasiya nümunəsi import java.util.ArrayList; import java.util.List; public class CopyIterationExample { public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("A"); list.add("B"); list.add("C"); // Surət yaradılır List<String> copyList = new ArrayList<>(list); for (String element : copyList) { System.out.println(element); // Orijinal kolleksiyanı dəyişə bilərsiniz, surətə təsir etməz if (element.equals("B")) { list.remove(element); } } System.out.println("Nəticə listi: " + list); } }
Yanaşma seçimi konkret tələblərdən asılıdır: kolleksiyanı iterasiya zamanı dəyişdirmək lazımdırmı, performans nə qədər vacibdir və kod çox iş parçacığı mühitində işləyirmi. CopyOnWriteArrayList/CopyOnWriteArraySet çox oxuma və az yazma üçün uyğundur. Kilidləmə daha az dəyişiklik olsa da, CopyOnWrite-ə nisbətən daha çox istifadə oluna bilər. Iterator.remove() və ya surət üzərində iterasiya yalnız bir iterasiya və ya iş parçacığında dəyişikliklər üçün uyğundur.