Sobes.tech
Middle

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:

  1. İş parçalarına qarşı təhlükəsiz kolleksiyaların istifadəsi: java.util.concurrent standart kolleksiyaların təhlükəsiz alternativlərini təqdim edir. Məsələn:

    • CopyOnWriteArrayList ArrayList yerinə
    • CopyOnWriteArraySet HashSet yerinə
    • ConcurrentHashMap HashMap yerinə
    // 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);
        }
    }
    
  2. Kolleksiyanı kilidləmək: synchronized və ya java.util.concurrent.locks istifadə 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
       }
    }
    
  3. 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);
        }
    }
    
  4. 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.