Iterator Fail-Selamat vs Iterator Fail-Cepat

1. Pengenalan

Dalam artikel ini, kami akan memperkenalkan konsep Iterator Fail-Cepat dan Gagal .

Sistem Fail-Cepat membatalkan operasi secepat mungkin dengan segera mendedahkan kegagalan dan menghentikan keseluruhan operasi.

Manakala, sistem Fail-Safe tidak membatalkan operasi sekiranya berlaku kegagalan. Sistem seperti itu cuba mengelakkan peningkatan kegagalan sebanyak mungkin.

2. Iterator Gagal-Cepat

Iterator cepat-cepat di Java tidak dapat dimainkan ketika koleksi yang mendasarinya diubah.

Koleksi mengekalkan kaunter dalaman yang disebut modCount . Setiap kali item ditambahkan atau dikeluarkan dari Koleksi , kaunter ini akan bertambah.

Semasa melakukan iterasi, pada setiap panggilan berikutnya () , nilai modCount semasa dibandingkan dengan nilai awal. Sekiranya terdapat ketidakcocokan, ia akan melancarkan ConcurrentModificationException yang membatalkan keseluruhan operasi.

Iterator lalai untuk Koleksi dari pakej java.util seperti ArrayList , HashMap , dll. Adalah Fail-Fast.

ArrayList numbers = // ... Iterator iterator = numbers.iterator(); while (iterator.hasNext()) { Integer number = iterator.next(); numbers.add(50); }

Dalam coretan kod di atas, ConcurrentModificationException akan dilemparkan pada permulaan kitaran lelaran seterusnya setelah pengubahsuaian dilakukan.

Tingkah laku Fail-Cepat tidak dijamin akan berlaku dalam semua senario kerana mustahil untuk meramalkan tingkah laku sekiranya berlaku pengubahsuaian bersamaan. Iterator ini melancarkan ConcurrentModificationException berdasarkan usaha terbaik .

Sekiranya semasa lelaran pada Koleksi , item dikeluarkan menggunakan kaedah Iterator 's remove () , itu benar-benar selamat dan tidak membuang pengecualian .

Walau bagaimanapun, jika Collection 's keluarkan () kaedah yang digunakan untuk mengeluarkan unsur, ia melemparkan pengecualian:

ArrayList numbers = // ... Iterator iterator = numbers.iterator(); while (iterator.hasNext()) { if (iterator.next() == 30) { iterator.remove(); // ok! } } iterator = numbers.iterator(); while (iterator.hasNext()) { if (iterator.next() == 40) { numbers.remove(2); // exception } }

3. Iterator Selamat-Gagal

Iterator Fail-Safe memihak kepada kekurangan kegagalan kerana ketidakselesaan pengendalian pengecualian

Iterator tersebut membuat klon Koleksi sebenar dan mengulanginya. Sekiranya ada pengubahsuaian berlaku setelah iterator dibuat, salinannya tetap tidak tersentuh. Oleh itu, Iterator ini terus menggunakan Koleksi walaupun ia diubah.

Walau bagaimanapun, penting untuk diingat bahawa tidak ada iterator Fail-Safe yang betul-betul. Istilah yang betul adalah Konsisten Lemah.

Ini bermaksud, jika Koleksi diubah semasa diulang, apa yang dilihat oleh Iterator dijamin lemah . Tingkah laku ini mungkin berbeza untuk Koleksi yang berbeza dan didokumentasikan dalam Javadocs setiap Koleksi tersebut .

Namun, Iterator Fail-Selamat mempunyai beberapa kelemahan. Satu kelemahan adalah bahawa Iterator tidak dijamin untuk mengembalikan data yang dikemas kini dari Koleksi , kerana ia berfungsi pada klon dan bukannya Koleksi yang sebenarnya .

Kelemahan lain adalah overhead membuat salinan Koleksi , baik mengenai masa dan ingatan.

Iterators pada Collections dari java.util.concurrent pakej seperti ConcurrentHashMap , CopyOnWriteArrayList , dan lain-lain Fail-Safe dalam alam semula jadi.

ConcurrentHashMap map = new ConcurrentHashMap(); map.put("First", 10); map.put("Second", 20); map.put("Third", 30); map.put("Fourth", 40); Iterator iterator = map.keySet().iterator(); while (iterator.hasNext()) { String key = iterator.next(); map.put("Fifth", 50); }

Dalam coretan kod di atas, kami menggunakan Iterator Fail-Selamat . Oleh itu, walaupun elemen baru ditambahkan ke Koleksi semasa lelaran, tidak ada pengecualian.

Iterator lalaiuntuk ConcurrentHashMap lemah secara konsisten. Ini bermaksud bahawa Iterator ini dapat bertolak ansur dengan pengubahsuaian serentak, melintasi unsur-unsur seperti yang ada ketika Iterator dibina dan mungkin (tetapi tidak dijamin) mencerminkan pengubahsuaian pada Koleksi setelah pembinaan Iterator .

Oleh itu, dalam coretan kod di atas, lelaran berulang lima kali, yang bermaksud ia mengesan elemen yang baru ditambahkan ke Koleksi .

4. Kesimpulan

Dalam tutorial ini, kita telah melihat apa yang dimaksudkan dengan Fail-Safe dan Fail-Fast Iterators dan bagaimana ini dilaksanakan di Java.

Kod lengkap yang disajikan dalam artikel ini boleh didapati di GitHub.