Разница между fail-fast и fail-safe итератором в Java

fail-fast Iterator

Итераторы в Java используются для итерации по объектам Collection. Fail-Fast итераторы немедленно вызывают ConcurrentModificationException, если есть структурная модификация коллекции. Структурная модификация означает добавление, удаление или обновление любого элемента из коллекции, когда поток выполняет итерацию по этой коллекции. Iterator в классах ArrayList, HashMap - это примеры fail-fast Iterator.

import java.util.ArrayList;
import java.util.Iterator;
 
public class FailFastIteratorExample {       
    public static void main(String[] args) {

        // Создание ArrayList целых чисел
        ArrayList<Integer> list = new ArrayList<Integer>();
         
        // Добавление элементов в список
        list.add(1452);
        list.add(6854);
        list.add(8741);
                 
        // Получение итератора из списка
        Iterator<Integer> it = list.iterator();
         
        while (it.hasNext()) {
            Integer integer = (Integer) it.next();
            // Это вызовет исключение 
            // ConcurrentModificationException
            list.add(8457);      
        }
    }   
}

Вывод:

Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
    at java.util.ArrayList$Itr.next(Unknown Source)
    at pack1.MainClass.main(MainClass.java:32)

fail-safe Iterator

fail-safe итераторы не генерируют никаких исключений, если коллекция структурно изменена во время итерации по ней. Это связано с тем, что они работают с клоном коллекции, а не с исходной коллекцией, и поэтому их называют fail-safe итераторами. Итератор в классах CopyOnWriteArrayList, ConcurrentHashMap являются примерами fail-safe итератора.

import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;
 
public class FailSafeIteratorExample {       
    public static void main(String[] args) {

        // Создание ConcurrentHashMap
        ConcurrentHashMap<String, Integer> map = 
            new ConcurrentHashMap<String, Integer>();
         
        // Добавляем элементы на карту
        map.put("ONE", 1);
        map.put("TWO", 2);
        map.put("THREE", 3);
         
        // Получение итератора из карты
        Iterator<String> it = map.keySet().iterator();
         
        while (it.hasNext()) {
            String key = (String) it.next();
            System.out.println(key+" : "+map.get(key));
            // Это не будет отражено в Iterator
            map.put("FOUR", 4);
        }
    }   
}

Вывод:

TWO : 2
FOUR : 4
ONE : 1
THREE : 3


Читайте также:


Комментарии

Популярные сообщения из этого блога

Методы класса Object в Java

Как получить текущий timestamp в Java

Основные опции JVM для повышения производительности и отладки