JavaRush /Blog Jawa /Random-JV /A Tale of Two Iterators: Competitive Modification Strateg...

A Tale of Two Iterators: Competitive Modification Strategy in Java

Diterbitake ing grup
Penulis cathetan kasebut yaiku Grzegorz Mirek, pangembang piranti lunak saka Krakow (Polandia). Dheweke wiwit berkembang ing Jawa kira-kira 6 taun kepungkur, nalika isih ana ing universitas, lan wiwit wektu iku dheweke ora leren nyegerake katrampilan ing babagan iki. Dheweke utamané kasengsem ing kinerja lan optimasi JVM, sing utamané ditulis ing blog .
A Tale of Two Iterators: Strategi Modifikasi Kompetitif ing Jawa - 1
Sawetara pitakonan wawancara Jawa paling populer kalebu: Apa prabédan antarane iterator gagal-cepet lan gagal-aman? Jawaban sing paling disederhanakake yaiku: A iterator gagal-cepet mbuwang ConcurrentModificationException yen koleksi owah-owahan sajrone pengulangan, nanging iterator gagal-aman ora. Senajan iki muni cukup migunani, iku tetep ora cetha apa interviewer tegese gagal-aman? Spesifikasi Basa Jawa ora nemtokake istilah iki gegayutan karo iterator. Nanging, ana papat strategi modifikasi kompetitif.

Modifikasi kompetitif

Pisanan, ayo nemtokake apa modifikasi kompetitif (utawa paralel). Ayo dadi ngomong kita duwe koleksi lan nalika iterator aktif, sawetara owah-owahan dumadi sing ora teka saka iterator iki. Ing kasus iki, kita entuk modifikasi kompetitif. Ayo kula menehi conto prasaja: kita duwe sawetara utas. Utas pisanan diulang, lan benang kapindho nglebokake utawa mbusak unsur saka koleksi sing padha. Nanging, kita bisa entuk ConcurrentModificationException nalika mlaku ing lingkungan siji-thread:
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

Gagal-cepet

Fragmen kode ing ndhuwur minangka conto iterator gagal-cepet . Nalika sampeyan bisa ndeleng, a ConcurrentModificationException dibuwang nalika nyoba njupuk unsur kapindho saka iterator . Kepiye carane iterator ngerti yen koleksi kasebut wis diowahi wiwit digawe? Contone, koleksi bisa duwe cap tanggal / wektu, ngandika lastModified . Nalika nggawe iterator, sampeyan kudu nyalin lapangan iki lan nyimpen ing obyek iterator. Banjur, saben wektu sabanjuré () cara disebut , sampeyan mung bakal mbandhingaké nilai lastModified saka koleksi karo salinan saka iterator. A pendekatan banget padha digunakake, contone, ing implementasine saka kelas ArrayList . Nduwe modCount variabel conto sing nyimpen kaping pirang-pirang dhaptar wis diowahi:
final void checkForComodification() {
   if (modCount != expectedModCount)
       throw new ConcurrentModificationException();
}
Wigati dimangerteni manawa iterator sing gagal cepet beroperasi kanthi basis paling apik, tegese ora ana jaminan yen ConcurrentModificationException bakal dibuwang yen ana modifikasi bebarengan. Dadi sampeyan ora kudu ngandelake - tinimbang, kudu digunakake kanggo ndeteksi kesalahan. Umume koleksi sing ora bebarengan nyedhiyakake iterator sing gagal .

Konsistensi Lemah

Umume koleksi bebarengan ing paket java.util.concurrent (kayata ConcurrentHashMap lan paling Queue ) nyedhiyakake iterator sing konsisten banget. Makna istilah iki diterangake kanthi apik ing dokumentasi :
  • Padha bisa diproses bebarengan karo operasi liyane
  • Dheweke ora tau mbuwang ConcurrentModificationException
  • Dijamin bakal ngliwati unsur sing ana nalika iterator digawe persis sapisan, lan bisa (nanging ora dibutuhake) nggambarake modifikasi sabanjure.

Snapshot

Kanthi strategi iki, iterator digandhengake karo kahanan koleksi nalika digawe - iki minangka snapshot saka koleksi kasebut. Sembarang owah-owahan sing digawe kanggo koleksi asli nyebabake nggawe versi anyar saka struktur data dhasar. Iki nggawe snapshot kita ora owah, saengga ora nggambarake owah-owahan ing koleksi sing kedadeyan sawise iterator digawe. Iki minangka teknik copy-on-write (COW) lawas sing apik . Iku rampung solves masalah modifikasi bebarengan, supaya ConcurrentModificationException ora kui karo pendekatan iki. Kajaba iku, iterator ora ndhukung operasi sing ngganti unsur. Koleksi copy-on-write cenderung larang banget kanggo digunakake, nanging bisa digunakake yen owah-owahan kedadeyan luwih jarang tinimbang traversal iterator. Conto kelas CopyOnWriteArrayList lan CopyOnWriteArraySet .

Prilaku sing ora ditemtokake

Sampeyan bisa uga nemoni prilaku sing ora ditemtokake ing jinis koleksi warisan kayata Vektor lan Hashtable . Loro-lorone duwe iterator standar gagal-cepet , nanging ing Kajaba iku, padha ngidini nggunakake implementasine saka antarmuka Enumeration , lan padha ora ngerti carane nindakake ing cilik saka modifikasi bebarengan. Sampeyan bisa uga nemokke sawetara unsur sing bola-bali utawa ilang, utawa malah sawetara pangecualian aneh. Iku luwih apik kanggo ora kanggo muter karo wong-wong mau!
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION