В Java есть два типа итераторов: отказоустойчивые и отказоустойчивые.
Что это значит, и чем они отличаются?
java
iterator
terminology
Prateek
источник
источник
Ответы:
«Отказоустойчивый» ( в инженерии ) означает, что что-то выходит из строя так, что не причиняет никакого ущерба или причиняет им минимальный ущерб. Строго говоря, в Java нет такого понятия, как отказоустойчивый итератор. Если итератор выходит из строя (в обычном смысле слова «сбой»), вы можете ожидать повреждения.
Я подозреваю, что вы на самом деле имеете в виду «слабо согласованные» итераторы. В javadoc говорится:
Как правило, слабая согласованность означает, что если коллекция изменяется одновременно с итерацией, гарантии того, что видит итерация, слабее. (Подробности будут указаны в документации javadocs для каждого параллельного набора классов.)
«Безотказный» ( в проектировании систем ) означает, что условие отказа тщательно проверяется, так что условие отказа (где возможно 1 ) обнаруживается до того, как может быть нанесен слишком большой ущерб. В Java отказоустойчивый итератор дает сбой, создавая
ConcurrentModificationException
.Альтернатива «отказоустойчивому» и «слабо согласованному» является семантическим, когда итерация терпит неудачу непредсказуемо; например, иногда давать неправильный ответ или генерировать неожиданное исключение. (Это было поведение некоторых стандартных реализаций
Enumeration
API в ранних версиях Java.)Нет. Это свойства итераторов, реализованные стандартными типами Collection; т.е. они либо «быстро выходят из строя», либо «слабо согласованы» ... при правильном использовании в отношении синхронизации и модели памяти Java 1 .
Отказоустойчивые итераторы обычно реализуются с использованием
volatile
счетчика в объекте коллекции.Iterator
создается, текущее значение счетчика внедряется вIterator
объект.Iterator
операция выполняется, метод сравнивает два значения счетчика и выдает CME, если они различны.Напротив, слабо согласованные итераторы обычно легковесны и используют свойства внутренних структур данных каждой параллельной коллекции. Общей закономерности нет. Если вам интересно, прочтите исходный код для разных классов коллекций.
1 - Наездник заключается в том, что безотказное поведение предполагает, что идентификатор приложения правильный в отношении синхронизации и модели памяти. Это означает, что (например), если вы выполняете итерацию
ArrayList
без надлежащей синхронизации, результатом может быть поврежденный результат списка. Механизм «быстрого сбоя», вероятно, обнаружит одновременную модификацию (хотя это не гарантируется), но не обнаружит лежащее в основе повреждение. Например, в javadoc forVector.iterator()
сказано следующее:источник
setArray
любые изменения.Это довольно отказоустойчивые и слабосогласованные типы:
Итераторы из
java.util
пакета бросают,ConcurrentModificationException
если коллекция была изменена методами коллекции (добавление / удаление) во время итерацииИтераторы из
java.util.concurrent
пакета обычно выполняют итерацию по снимку и допускают одновременные изменения, но могут не отражать обновления коллекции после создания итератора.источник
Iterator
или неEnumeration
указывайте поведение как отказоустойчивое или отказоустойчивое. Это конкретные реализации (т.е. определенные методы коллекцииiterator()
/ иelements()
т.д., которые возвращают эти объекты), которые определяют поведение. 2) Типичные реализации перечисления не являются ни отказоустойчивыми, ни отказоустойчивыми .Единственная разница в том, что отказоустойчивый итератор не генерирует никаких исключений, в отличие от отказоустойчивого итератора.
Если Collection модифицируется структурно, пока один поток выполняет итерацию по нему. Это связано с тем, что они работают с клоном Collection вместо исходной коллекции, и поэтому они называются отказоустойчивым итератором.
Итератор CopyOnWriteArrayList является примером отказоустойчивого итератора. Итератор, написанный ConcurrentHashMap keySet, также является отказоустойчивым итератором и никогда не генерирует исключение ConcurrentModificationException в Java.
источник
Этот сценарий связан с «параллельной обработкой», что означает, что к одному и тому же ресурсу обращаются более одного пользователя. В такой ситуации один из пользователей пытается изменить этот ресурс, что вызывает исключение ConcurrentProcessingException, потому что в этом случае другой пользователь получает неправильные данные. Оба эти типа относятся к подобным ситуациям.
Проще говоря,
Быстрый отказ:
Отказоустойчивый:
источник