На Java існує два типи ітераторів: безпечний та безвідмовний.
Що це означає, і чи є різниця між ними?
На Java існує два типи ітераторів: безпечний та безвідмовний.
Що це означає, і чи є різниця між ними?
Відповіді:
Яка різниця між ними ...
"Наявність відмов" ( в техніці ) означає, що щось виходить з ладу таким чином, що не завдає ніякої або мінімальної шкоди. Власне кажучи, у Java немає такого поняття, як ідентифікатор відмови. Якщо ітератор виходить з ладу (у звичайному розумінні "виходить з ладу"), ви можете очікувати, що це може призвести до пошкодження.
Я підозрюю, що ви насправді маєте на увазі "слабо послідовних" ітераторів. Явадок каже:
"Більшість одночасних реалізацій колекції (включаючи більшість черг) також відрізняються від звичайних конвенцій java.util тим, що їх Ітератори та Спілітератори забезпечують слабко послідовний, а не швидкий вихід з ладу."
Зазвичай слабка консистенція означає, що якщо колекція модифікується одночасно з ітерацією, гарантії того, що бачить ітерація, слабкіші. (Деталі будуть вказані у кожному паралельному класі колекціонування javadocs.)
"Невдалий збій" ( в дизайні систем ) означає, що стан відмови перевіряється агресивно, щоб було виявлено стан відмови (де це можливо 1 ) перед тим, як завдати занадто великої шкоди. У Java невдалий ітератор виходить з ладу, кинувши a ConcurrentModificationException
.
Альтернатива "невдалому" та "слабо послідовному" є семантичним, коли ітерація не вдається непередбачувано; наприклад, іноді дати неправильну відповідь або кинути несподіваний виняток. (Це було поведінкою деяких стандартних реалізацій Enumeration
API в ранніх версіях Java.)
... і чим вони відрізняються від ітератора, який ми використовуємо для колекції.
Ні. Це властивості ітераторів, реалізованих стандартними типами колекції; тобто вони або "швидко виходять з ладу", або "слабо узгоджуються" ... при правильному використанні стосовно синхронізації та моделі пам'яті Java 1 .
Збійні ітератори зазвичай реалізуються за допомогою volatile
лічильника на об'єкті колекції.
Iterator
створюється, поточне значення лічильника вбудовується в Iterator
об'єкт.Iterator
виконується операція, метод порівнює два значення лічильника і кидає CME, якщо вони різні.На противагу цьому, слабо послідовні ітератори мають типову легку вагу та властивості використання внутрішніх структур даних кожного паралельного збору. Загальної закономірності немає. Якщо вас цікавить, прочитайте вихідний код для різних класів колекції.
1 - Наїзник полягає в тому, що невдала поведінка передбачає, що програма ідентифікує правильно стосовно синхронізації та моделі пам'яті. Це означає, що (наприклад), якщо ви повторюєте ArrayList
без належної синхронізації, результат може бути пошкодженим результатом списку. Механізм "швидкого виходу з ладу", ймовірно, виявить одночасну модифікацію (хоча це не гарантується), але він не виявить основної корупції. Як приклад, javadoc for Vector.iterator()
говорить про це:
"Неможливо гарантувати поведінку ітератора, оскільки це, загалом кажучи, неможливо дати будь-які жорсткі гарантії за наявності несинхронізованих одночасних модифікацій. Невдалі ітератори відкидаються
ConcurrentModificationException
на основі найкращих зусиль. Тому було б неправильно писати програму, яка залежала від цього винятку за її правильність: невдала поведінка ітераторів повинна використовуватися лише для виявлення помилок ".
setArray
будь-які зміни.
Вони досить швидкі та слабкозмінні типи:
Ітератори від java.util
кидання пакетуConcurrentModificationException
якщо колекція була змінена методами колекції (додавання / видалення) під час ітерації
Ітератори з java.util.concurrent
пакету зазвичай ітератують під час знімка та дозволяють одночасно змінювати, але можуть не відображати оновлення колекції після створення ітератора.
Iterator
та не Enumeration
вказуйте поведінку як невдалий або невдалий. Саме поведінка визначає конкретні реалізації (тобто конкретні методи колекції iterator()
/ elements()
тощо), які визначають поведінку. 2) Типові реалізації перерахування не є ані швидкими, ані безпечними .
Єдина відмінність полягає в тому, що безпечний ітератор не викидає жодного винятку, на відміну від швидкодіючого ітератора.
Якщо колекція структурно модифікована, тоді як одна нитка перекручується над нею. Це відбувається тому, що вони працюють над клоном колекції замість оригінальної колекції, і тому їх називають невідправним ітератором.
Iterator CopyOnWriteArrayList є прикладом невдалого Iterator також ітератора, написаного ConcurrentHashMap keySet також є безпечним ітератором і ніколи не кидає ConcurrentModificationException в Java.
Цей сценарій пов'язаний з "одночасною обробкою", означає, що більше одного користувача отримують доступ до одного і того ж ресурсу. У такій ситуації один з користувачів намагається змінити той ресурс, який викликає "ConcurrentProcessingException", оскільки в такому випадку інший користувач отримує неправильні дані. Обидва цього типу пов'язані з такою ситуацією.
Простіше кажучи,
Невдалий:
Безаварійності :