Предыдущий обзор:Как много вы знаете о принципе доступа HashMapd?
今天,我们来谈谈fail-fast与fail-safe是什么以及工作机制
Что такое отказоустойчивость?
fail-fast буквально означает «быстро терпеть неудачу». Когда мы обходим элементы коллекции, мы часто используем итераторы, но в процессе обхода элементов итератором, если структура коллекции изменяется, будет выдано исключение, чтобы предотвратить продолжение обхода. Это так называемый отказоустойчивый механизм.
Давайте посмотрим, как официальный документ объясняет отказоустойчивость в коллекции HashMap (как показано ниже):
То есть, когда итератор создается, в дополнение к методу (удалить) самого итератора, который может изменить структуру коллекции, другие факторы, такие какИзменена структура коллекции, выбрасываются исключения ConcurrentModificationException.
Пожалуйста, продолжайте читать официальное описание:
Это означает, что безотказное поведение итераторов не обязательно гарантируется, и, вообще говоря, невозможно дать какие-либо твердые гарантии при наличии асинхронных одновременных модификаций. Но отказоустойчивые итераторы делают все возможное, чтобы генерировать исключение ConcurrentModificationException. Поэтому некорректно писать программы, зависящие от этого исключения. Правильный подход должен быть таким: безотказное поведение итераторов следует использовать только для обнаружения ошибок в программах.
Подводя небольшой итог: fail-fast, механизм быстрого отказа, является механизмом обнаружения ошибок в java-коллекции.При нескольких потоках (и каждый поток также может оторваться), когда коллекция структурно изменена, возможен сбой -быстрый механизм будет сгенерирован.
Здесь я объясняю, что такое структурное изменение. Например, вставка и удаление коллекции является структурным изменением, но если это изменение элемента в коллекции, это не является структурным изменением.
Далее давайте продемонстрируем пример отказоустойчивого генерирования исключения в однопоточной среде:
for(int i = 10; i < 100; i++){
map.put(i, i);
}
List<Integer> list = new ArrayList<>();
for(int i = 0; i < 20; i++){
list.add(i);
}
Iterator<Integer> it = list.iterator();
int temp = 0;
while(it.hasNext()){
if(temp == 3){
temp++;
list.remove(3);
}else{
temp++;
System.out.println(it.next());
}
}
}
распечатать результат:
**Анализ результатов:** Поскольку метод list.remove() выполняется, когда temp==3, структура коллекции изменяется, поэтому при повторном обходе итератора будет выдано исключение.
Как работает отказоустойчивость
Давайте сначала посмотрим на исходный код:
** Анализ: ** Мы можем видеть из исходного кода, в реализации итератора next() и других методов вызовет checkForComodification() этот метод, см. modCount == expectModCount выдает исключение, если равно?.
ожидаемыйModcount: этому значению присваивается фиксированное значение modCount при создании объекта. То есть значение постоянное. То есть, если значение modCount изменяется, когда итератор проходит элементы, при повторном обходе будет выдано исключение.
Когда изменится modCount?
На этот раз я не буду показывать вам исходный код. На самом деле, когда мы изменим количество элементов в коллекции, значение modCount будет изменено, если удалено, то вставлено. Но модификации нет.
Некоторые методы работы с отказоустойчивыми
Если мы не хотим, чтобы структура коллекции изменялась из-за параллелизма и других причин при обходе итератора, и тогда может быть выброшено исключение, мы можем добавить синхронизированную блокировку в место, влияющее на изменение значения modCount. , или использовать напрямую Collections.synchronizedList для решения.
Fast-Fast расскажет об этом первым, и разница между неудачным и неудачным быстро
Когда мы вносим изменения в структуру коллекции, отказоустойчивый механизм выдает исключение. Однако для отказоустойчивого механизма исключения не будут выброшены (вероятно, вы знаете слово безопасный, когда его видите).
Это связано с тем, что при изменении структуры коллекции отказоустойчивый механизм скопирует копию исходных данных коллекции, а затем пройдет по скопированным данным.
Таким образом, хотя отказоустойчивость не генерирует исключений, у нее есть следующие недостатки:
-
Для копирования требуется дополнительное пространство и время.
-
Нет никакой гарантии, что прохождение является последним контентом.
Если статья неверна, поправьте меня. Если вы привыкли читать технические статьи о WeChat и хотите получить больше других ресурсов, вы можете обратить внимание на публичный аккаунт WeChat: Трудолюбивый фермер кода
Я надеюсь, что вы что-то почерпнете из этого, это моя самая большая награда!