Ответ
Fail-fast — это поведение итератора коллекции, при котором он немедленно выбрасывает исключение ConcurrentModificationException, если обнаруживает структурное изменение коллекции (добавление, удаление элементов) любым способом, кроме собственных методов итератора, во время итерации.
Цель: Предотвратить неопределенное поведение и помочь быстро найти ошибку синхронизации в коде.
Пример, вызывающий исключение:
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
for (String item : list) { // Неявно используется Iterator<String>
if (item.equals("B")) {
list.remove(item); // Модификация коллекции НЕ через итератор!
// Выбросит ConcurrentModificationException
}
}
Как работает: Итератор хранит внутренний счетчик модификаций коллекции (modCount). При каждой операции итерации (hasNext(), next()) он сравнивает сохраненное значение с текущим modCount. Если они различаются — бросается исключение.
Корректные способы модификации во время итерации:
- Использовать методы самого итератора:
Iterator<String> iterator = list.iterator(); while (iterator.hasNext()) { String item = iterator.next(); if (item.equals("B")) { iterator.remove(); // Безопасное удаление } } - Использовать fail-safe коллекции из пакета
java.util.concurrent(например,CopyOnWriteArrayList,ConcurrentHashMap). Они работают с копией данных и не бросают это исключение.
Fail-fast коллекции: ArrayList, HashMap, HashSet, Vector (и его Enumeration).
Важно: Fail-fast не гарантирует обнаружение всех асинхронных модификаций, это механизм для отладки, а не для контроля потокобезопасности.