Qeydin müəllifi Krakovdan (Polşa) proqram təminatı tərtibatçısı Qrzeqorz Mirekdir. O, təxminən 6 il əvvəl, hələ universitetdə oxuyarkən Java-da inkişaf etməyə başlayıb və o vaxtdan bu sahədə öz bacarıqlarını yorulmadan cilalayır. O, JVM performansı və optimallaşdırılması ilə xüsusilə maraqlanır, bu barədə əsasən bloqunda yazır .
Java-nın ən populyar müsahibə suallarından bəziləri bunlardır: Fast-fast və fail-safe iteratorlar arasında fərq nədir? Buna ən sadələşdirilmiş cavab belədir: Uğursuz-sürətli iterator, iterasiya zamanı kolleksiya dəyişirsə, ConcurrentModificationException atır, lakin uğursuz iterator dəyişmir. Bu kifayət qədər mənalı səslənsə də, müsahibin uğursuzluqla nə demək istədiyi aydın deyil? Java Dil Spesifikasiyaları bu termini iteratorlara münasibətdə müəyyən etmir. Bununla belə, dörd rəqabətli modifikasiya strategiyası mövcuddur.
Rəqabətli modifikasiya
Əvvəlcə rəqabətli (və ya paralel) modifikasiyanın nə olduğunu müəyyən edək. Tutaq ki, bizim kolleksiyamız var və iterator aktiv olduqda, bu iteratordan gəlməyən bəzi dəyişikliklər baş verir. Bu halda, biz rəqabətli modifikasiya alırıq. Sizə sadə bir misal verim: tutaq ki, bizdə bir neçə mövzu var. Birinci ip təkrarlanır və ikinci ip eyni kolleksiyadan elementləri daxil edir və ya çıxarır. Bununla belə, biz tək yivli mühitdə işləyərkən ConcurrentModificationException əldə edə bilərik:List<String> cities = new ArrayList<>();
cities.add(“Warsaw”);
cities.add(“Prague”);
cities.add(“Budapest”);
Iterator<String> cityIterator = cities.iterator();
cityIterator.next();
cities.remove(1);
cityIterator.next(); // генерирует ConcurrentModificationException
Tez uğursuz
Yuxarıdakı kod parçası uğursuz sürətli iteratorun nümunəsidir . Gördüyünüz kimi, iteratordan ikinci elementi götürməyə çalışarkən ConcurrentModificationException atıldı . İterator kolleksiyanın yaradılandan bəri dəyişdirildiyini necə bilir? Məsələn, kolleksiyada tarix/saat möhürü ola bilər, deyək lastModified . İterator yaratarkən bu sahəni köçürməli və onu iterator obyektində saxlamalısınız. Sonra hər dəfə növbəti() metodu çağırılanda siz sadəcə olaraq kolleksiyadakı lastModified dəyərini iteratordan olan surətlə müqayisə edəcəksiniz . Çox oxşar yanaşma, məsələn, ArrayList sinifinin həyata keçirilməsində istifadə olunur . Siyahının neçə dəfə dəyişdirildiyini saxlayan modCount nümunə dəyişəninə malikdir :final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
Qeyd etmək vacibdir ki, uğursuz sürətli iteratorlar ən yaxşı cins əsasında işləyir, yəni paralel modifikasiya zamanı ConcurrentModificationException-ın atılacağına zəmanət yoxdur . Beləliklə, onlara etibar etməməlisiniz - daha doğrusu, səhvləri aşkar etmək üçün istifadə edilməlidir. Əksər paralel olmayan kolleksiyalar uğursuz sürətli iteratorları təmin edir.
Zəif Ardıcıllıq
Java.util.concurrent paketindəki əksər paralel kolleksiyalar (məsələn, ConcurrentHashMap və most Queue kimi ) zəif ardıcıl iteratorları təmin edir. Bu terminin mənası sənədlərdə çox yaxşı izah edilmişdir :- Onlar digər əməliyyatlarla eyni vaxtda işlənə bilər
- Heç vaxt ConcurrentModificationException atmırlar
- Onlara iteratorun tam olaraq bir dəfə yaradıldığı anda mövcud elementləri keçməsinə zəmanət verilir və sonrakı dəyişiklikləri əks etdirə bilər (lakin tələb olunmur).
GO TO FULL VERSION