Рубрики
Без рубрики

Fail-Безопасный Итератор против Fail-Быстрый Итератор

Быстрое и практическое сравнение отказобезопасных и отказоемкости итераторов на Java.

Автор оригинала: baeldung.

1. Введение

В этой статье мы представим концепцию Fail-Fast и Fail-Safe Итераторы .

Отказ-Быстрые системы прерывают работу как можно быстрее, немедленно обнажая сбои и останавливая всю операцию.

В то время как Системы fail-Safe не прерываются операцию в случае сбоя. Такие системы стараются как можно больше избегать сбоев.

2. Отказ-быстрые итераторы

Быстро итераторы в Java не подыграют, когда базовая коллекция изменяется.

Коллекции поддерживать внутренний счетчик под названием modCount . Каждый раз, когда элемент добавляется или удаляется из Коллекционая , этот счетчик получает приращения.

При итерации, на каждом Далее () вызова, текущее значение modCount сравнивается с первоначальным значением. Если есть несоответствие, это бросает ПараллельноМодификацияИсключение который прерывает всю операцию.

Итераторы по умолчанию для Коллекции От пакет java.util как ArrayList , ХэшМэп и т.д. являются Fail-Быстрый.

ArrayList numbers = // ...

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

В фрагменте кода выше, ПараллельноМодификацияИсключение получает бросили в начале следующего цикла итерации после изменения была выполнена.

Поведение Fail-Fast не гарантируется во всех сценариях, так как невозможно предсказать поведение в случае параллельных изменений. Эти итераторы бросают ПараллельноМодификацияИсключение на основе наилучших усилий .

Если во время итерации в течение Коллекционая , элемент удаляется с помощью Итератор ‘ы удалить () метод, это совершенно безопасно и не бросает исключение .

Однако, если Коллекционая ‘ы удалить () метод используется для удаления элемента, он бросает исключение:

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. Отказобезопасные Итераторы

Итераторы Fail-Safe выступают за отсутствие сбоев из-за неудобства обработки исключений.

Эти итераторы создают клон фактического Коллекционая и итерировать над ним. Если какая-либо модификация происходит после создания итератора, копия остается нетронутой. Следовательно, эти Итераторы продолжать цикл над Коллекционая даже если он изменен.

Тем не менее, важно помнить, что нет такой вещи, как действительно Fail-Безопасный итератор. Правильный термин слабо последовательный.

Это значит, если Коллекционая изменяется при итерировании, что Итератор видит слабо гарантировано . Такое поведение может быть разным для разных Коллекции и документируется в Javadocs каждого такого Коллекционая .

Безопасный для Итераторы есть несколько недостатков, однако. Одним из недостатков является то, Итератор не гарантируется возврат обновленных данных с Коллекционая , как он работает на клона, а не фактической Коллекционая .

Другим недостатком является накладные расходы на создание копии Коллекционая , как в отношении времени и памяти.

Итераторы на Коллекции От java.util.concurrent пакет, такой как ПараллельныйHashMap , CopyOnWriteArrayList , и т.д. являются Fail-Safe в природе.

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);
}

В фрагменте кода выше, мы используем Fail-Safe Итератор . Таким образом, даже если новый элемент добавляется в Коллекционая во время итерации он не делает исключение.

Итератор по умолчанию для ПараллельноHashMap слабо последовательна. Это означает, что Итератор может терпеть одновременные изменения, пересекает элементы, как они существовали, Итератор был построен и может (но не гарантируется) отражают изменения в Коллекционая после строительства Итератор .

Таким образом, в фрагменте кода выше, итерация циклы пять раз, что означает он обнаруживает недавно добавленный элемент в Коллекционая .

4. Заключение

В этом учебнике мы видели, что Fail-Safe и Fail-Fast Итераторы означает и как они реализуются в Java.

Полный код, представленный в этой статье, доступен более на GitHub .