Java fail fast iterator

Сказ о двух итераторах: стратегии конкурентной модификации в Java

Java-университет

Автор заметки — Гжегож Мирек — разработчик программного обеспечения из Кракова (Польша). Он занялся разработкой на Java около 6 лет назад, ещё в университете, и, с этого времени, неустанно шлифует своё мастерство в данной сфере. Его особенно интересует вопрос производительности JVM и оптимизации, о чем он, в основном, и пишет в своём блоге.

Сказ о двух итераторах: стратегии конкурентной модификации в Java - 1

Среди наиболее популярных вопросов на собеседованиях по языку 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 итераторы.

Читайте также:  Underline tag in css

Слабая согласованность

  • Они могут обрабатываться конкурентно с другими операциями
  • Они никогда не генерируют исключение 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

  • Получить ссылку
  • Facebook
  • Twitter
  • Pinterest
  • Электронная почта
  • Другие приложения
Читайте также:  Vestacp ubuntu обновить php

Комментарии

Отправить комментарий

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

Методы класса 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

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

Источник

Java fail fast iterator

Learn Latest Tutorials

Splunk tutorial

SPSS tutorial

Swagger tutorial

T-SQL tutorial

Tumblr tutorial

React tutorial

Regex tutorial

Reinforcement learning tutorial

R Programming tutorial

RxJS tutorial

React Native tutorial

Python Design Patterns

Python Pillow tutorial

Python Turtle tutorial

Keras tutorial

Preparation

Aptitude

Logical Reasoning

Verbal Ability

Company Interview Questions

Artificial Intelligence

AWS Tutorial

Selenium tutorial

Cloud Computing

Hadoop tutorial

ReactJS Tutorial

Data Science Tutorial

Angular 7 Tutorial

Blockchain Tutorial

Git Tutorial

Machine Learning Tutorial

DevOps Tutorial

B.Tech / MCA

DBMS tutorial

Data Structures tutorial

DAA tutorial

Operating System

Computer Network tutorial

Compiler Design tutorial

Computer Organization and Architecture

Discrete Mathematics Tutorial

Ethical Hacking

Computer Graphics Tutorial

Software Engineering

html tutorial

Cyber Security tutorial

Automata Tutorial

C Language tutorial

C++ tutorial

Java tutorial

.Net Framework tutorial

Python tutorial

List of Programs

Control Systems tutorial

Data Mining Tutorial

Data Warehouse Tutorial

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 RSS Feed Subscribe to Get Email Alerts Facebook Page Twitter Page YouTube Blog Page

Источник

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.

Источник

Оцените статью