- Fail Fast and Fail Safe Iterators in Java
- Сказ о двух итераторах: стратегии конкурентной модификации в Java
- Конкурентная модификация
- Fail-fast
- Слабая согласованность
- Снимок состояния
- Неопределенное поведение
- Java Blog
- fail-safe Iterator
- Комментарии
- Отправить комментарий
- Популярные сообщения из этого блога
- Методы класса Object в Java
- Как получить текущий timestamp в Java
- Spring Boot стартеры
- Java fail safe iterator
- Learn Latest Tutorials
- Preparation
- Trending Technologies
- B.Tech / MCA
- Javatpoint Services
- Training For College Campus
Fail Fast and Fail Safe Iterators in Java
In this article, I am going to explain how those collections behave which doesn’t iterate as fail-fast. First of all, there is no term as fail-safe given in many places as Java SE specifications does not use this term. I am using fail safe to segregate between Fail fast and Non fail-fast iterators.
Concurrent Modification: Concurrent Modification in programming means to modify an object concurrently when another task is already running over it. For example, in Java to modify a collection when another thread is iterating over it. Some Iterator implementations (including those of all the general purpose collection implementations provided by the JRE) may choose to throw ConcurrentModificationException if this behavior is detected.
Fail Fast And Fail Safe Iterators in Java
Iterators in java are used to iterate over the Collection objects.Fail-Fast iterators immediately throw ConcurrentModificationException if there is structural modification of the collection. Structural modification means adding, removing any element from collection while a thread is iterating over that collection. Iterator on ArrayList, HashMap classes are some examples of fail-fast Iterator.
Fail-Safe iterators don’t throw any exceptions if a collection is structurally modified while iterating over it. This is because, they operate on the clone of the collection, not on the original collection and that’s why they are called fail-safe iterators. Iterator on CopyOnWriteArrayList, ConcurrentHashMap classes are examples of fail-safe Iterator.
How Fail Fast Iterator works ?
To know whether the collection is structurally modified or not, fail-fast iterators use an internal flag called modCount which is updated each time a collection is modified.Fail-fast iterators checks the modCount flag whenever it gets the next value (i.e. using next() method), and if it finds that the modCount has been modified after this iterator has been created, it throws ConcurrentModificationException.
Сказ о двух итераторах: стратегии конкурентной модификации в Java
Автор заметки — Гжегож Мирек — разработчик программного обеспечения из Кракова (Польша). Он занялся разработкой на Java около 6 лет назад, ещё в университете, и, с этого времени, неустанно шлифует своё мастерство в данной сфере. Его особенно интересует вопрос производительности JVM и оптимизации, о чем он, в основном, и пишет в своём блоге.
Среди наиболее популярных вопросов на собеседованиях по языку Java есть и такой: В чём различие между fail-fast и fail-safe итераторами? Максимально упрощённый ответ на него: Fail-fast итератор генерирует исключение ConcurrentModificationException, если коллекция меняется во время итерации, а fail-safe – нет. Хотя это звучит достаточно осмысленно, остается непонятным, что интервьюер понимает под fail-safe? Спецификации языка Java не определяют этот термин в отношении итераторов. Однако существуют четыре стратегии конкурентной модификации.
Конкурентная модификация
Во-первых, давайте определимся, что такое конкурентная (или параллельная) модификация. Допустим у нас есть коллекция и при активном итераторе происходят какие-либо её изменения, не исходящие от данного итератора. В таком случае у нас получается конкурентная модификация. Приведу простейший пример: допустим, у нас есть несколько нитей. Первая нить выполняет итерации, а вторая вставляет элементы в ту же коллекцию или удаляет их из неё. Однако мы можем получить исключение ConcurrentModificationException и при работе в однопоточной среде:
List<String> cities = new ArrayList<>(); cities.add(“Warsaw”); cities.add(“Prague”); cities.add(“Budapest”); Iterator<String> cityIterator = cities.iterator(); cityIterator.next(); cities.remove(1); cityIterator.next(); // генерирует ConcurrentModificationException
Fail-fast
Вышеприведенный фрагмент кода – пример fail-fast итератора. Как вы можете видеть, при попытке извлечения второго элемента из итератора было сгенерировано исключение ConcurrentModificationException. Откуда итератор узнает, что коллекция была модифицирована после его создания? Например, в коллекции может быть метка даты/времени, скажем, lastModified. При создании итератора вам стоит скопировать это поле и сохранить его в объекте итератора. Затем, при каждом вызове метода next(), нужно будет просто сравнить значение lastModified из коллекции с копией из итератора. Очень близкий подход используется, например, в реализации класса ArrayList. В нём есть переменная экземпляра modCount, в которой хранится количество модификаций списка:
final void checkForComodification()
Важно отметить, что fail-fast итераторы работают на основе принципа «по мере возможности», то есть не дается никаких гарантий генерации исключения ConcurrentModificationException в случае конкурентной модификации. Так что полагаться на это не стоит – скорее, их следует использовать для обнаружения ошибок. Большинство неконкурентных коллекций предоставляют fail-fast итераторы.
Слабая согласованность
- Они могут обрабатываться конкурентно с другими операциями
- Они никогда не генерируют исключение ConcurrentModificationException
- Они гарантированно обходят существовавшие на момент создания итератора элементы ровно один раз, и могут (но не обязаны) отражать последующие модификации.
Снимок состояния
При такой стратегии итератор связывается с состоянием коллекции на момент его создания – это и есть снимок состояния (снепшот) коллекции. Любые произведенные над исходной коллекцией изменения приводят к созданию новой версии нижележащей структуры данных. При этом наш снимок состояния остается неизменным, так что он не отражает изменения в коллекции, которые произошли после создания итератора. Это старая добрая методика копирования при записи (copy-on-write, COW). Она полностью решает проблему конкурентных модификаций, поэтому исключение ConcurrentModificationException при таком подходе не генерируется. Кроме того, итераторы не поддерживают операции, которые меняют элементы. Коллекции с копированием при записи обычно требуют слишком больших расходов ресурсов при использовании, но имеет смысл воспользоваться ими, если изменения происходят намного реже, чем обходы итераторов. Примерами могут служить классы CopyOnWriteArrayList и CopyOnWriteArraySet.
Неопределенное поведение
Неопределенное поведение может встретиться вам в устаревших унаследованных типах коллекций, таких как Vector и Hashtable. В обеих есть стандартные fail-fast итераторы, но кроме этого, они позволяет использовать реализации интерфейса Enumeration, а они не знают, как себя вести в случае конкурентной модификации. Вы можете столкнуться с тем, что некоторые элементы повторяются или оказываются пропущенными, а то и вовсе увидите какие-то странные исключения. Лучше с ними не играться!
Java Blog
Итераторы в 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 целых чисел ArrayListlist = new ArrayList(); // Добавление элементов в список list.add(1452); list.add(6854); list.add(8741); // Получение итератора из списка Iterator 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 ConcurrentHashMapmap = new ConcurrentHashMap(); // Добавляем элементы на карту map.put("ONE", 1); map.put("TWO", 2); map.put("THREE", 3); // Получение итератора из карты Iterator 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
Класс Object является корнем иерархии классов. У каждого класса есть Object как суперкласс. Все объекты, включая массивы, реализуют методы этого класса. Методы класса Object Метод getClass() public final Class getClass() Возвращает класс времени исполнения (runtime class) этого Object. Возвращенный объект Class — это объект, который заблокирован статическими синхронизированными методами представленного класса. Фактический тип результата — Class где |X| заменяется статическим типом выражения, для которого вызывается getClass. Например, в этом фрагменте кода не требуется приведение: Number n = 0; Class c = n.getClass(); Метод getClass() возвращает: Объект Class, представляющий класс времени исполнения (runtime class) этого объекта. Метод hashCode public int hashCode() Возвращает значение хэш-кода для объекта. Этот метод поддерживается для использования хэш-таблиц, таких как те, что предоставляются HashMap. Основной контракт метода hashCo?>
Как получить текущий timestamp в Java
Чтобы получить текущий timestamp в Java : package main; import java.sql.Timestamp; public class Main < public static void main(String[] args)< Timestamp timestamp = new Timestamp(System.currentTimeMillis()); System.out.println(timestamp); >> Вывод: 2019-10-03 10:09:21.61 Вот еще два более подробных примера как получить текущий timestamp в Java: 1. java.sql.Timestamp Есть два метода получить текущий java.sql.Timestamp package main; import java.sql.Timestamp; import java.text.SimpleDateFormat; import java.util.Date; public class Main < private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss"); public static void main(String[] args) < // Метод 1 Timestamp timestamp = new Timestamp(System.currentTimeMillis()); System.out.println(timestamp); // Метод 2 - через Date Date date = new Date(); System.out.println(new Timestamp(date.getTime()
Spring Boot стартеры
Стартеры — это набор удобных дескрипторов зависимостей, которые вы можете включить в свое приложение. Вы получаете универсальный набор для всех необходимых вам Spring и связанных с ними технологий без необходимости искать примеры кода и копировать и вставлять множество дескрипторов зависимостей. Например, если вы хотите начать использовать Spring и JPA для доступа к базе данных, включите в ваш проект зависимость spring-boot-starter-data-jpa. Стартеры содержат множество зависимостей, которые необходимы вам для быстрого запуска и запуска проекта с согласованным, поддерживаемым набором управляемых переходных зависимостей. Что указывается в имени стартера Все официальные стартеры следуют аналогичной схеме именования; spring-boot-starter-*, где * это конкретный тип приложения. Эта структура наименования предназначена, чтобы помочь, когда вам нужно найти стартер. Интеграция Maven во многие IDE позволяет вам искать зависимости по имени. Например, если установлен соответствующий плагин Ecl
Java fail safe iterator
Learn Latest Tutorials
Preparation
Trending Technologies
B.Tech / MCA
Javatpoint Services
JavaTpoint offers too many high quality services. Mail us on h[email protected], to get more information about given services.
- Website Designing
- Website Development
- Java Development
- PHP Development
- WordPress
- Graphic Designing
- Logo
- Digital Marketing
- On Page and Off Page SEO
- PPC
- Content Development
- Corporate Training
- Classroom and Online Training
- Data Entry
Training For College Campus
JavaTpoint offers college campus training on Core Java, Advance Java, .Net, Android, Hadoop, PHP, Web Technology and Python. Please mail your requirement at [email protected].
Duration: 1 week to 2 week
Like/Subscribe us for latest updates or newsletter