Например, Карта контейнера в Java:
for(Человек человек: pList){
if(person.getGender()==Gender.MALE){
pList.remove(person); //Операция удаления не может быть выполнена во время обхода
}
}
При перемещении по карте он обычно получает набор значений ключей, а затем использует итератор для перемещения по карте.
Обратите внимание, что в процессе обхода соответствующим образом могут обрабатываться только элементы карты. Другими словами, размер карты не может быть изменен, и возникнет исключение (невозможно использовать во время). процесс обхода), изменять, удалять или добавлять элементы на карте)
Сообщается об исключении java.util.ConcurrentModificationException.
общедоступный класс ConcurrentModificationExceptionextends RuntimeException
Это исключение генерируется, когда метод обнаруживает одновременную модификацию объекта, но не разрешает такую модификацию.
Например, пока один поток выполняет итерацию по коллекции, другому потоку обычно не разрешается линейно изменять коллекцию. Часто в этих случаях результаты итерации неясны. Некоторые реализации итераторов (включая все реализации универсальных коллекций, предоставляемые JRE) могут выдать это исключение, если такое поведение обнаружено. Итераторы, выполняющие эту операцию, называются отказоустойчивыми итераторами, поскольку итератор выходит из строя очень быстро без риска произвольного неопределенного поведения в какой-то момент в будущем.
Обратите внимание, что это исключение не всегда будет указывать на то, что объект был изменен одновременно разными потоками. Объект может выдать это исключение, если один поток выдает последовательность вызовов методов, нарушающих контракт объекта. Например, если поток напрямую изменяет коллекцию, проходя по ней с помощью отказоустойчивого итератора, итератор выдаст это исключение.
Обратите внимание, что отказоустойчивое поведение итераторов не гарантируется, поскольку, как правило, невозможно дать какие-либо твердые гарантии относительно того, будут ли происходить несинхронизированные одновременные изменения. Операции с отказоустойчивостью создают исключение ConcurrentModificationException при необходимости. Поэтому писать программу, которая использует это исключение для повышения корректности таких операций, является ошибкой. Правильный подход: ConcurrentModificationException следует использовать только для обнаружения ошибок.
При попытке напрямую изменить содержимое коллекции/карты с использованием отказоустойчивого итератора для перебора коллекции или карты будет выдано исключение java.util.ConcurrentModificationException даже при работе в одном потоке.
Итератор работает в отдельном потоке и имеет блокировку мьютекса. После создания Итератора будет создана односвязная индексная таблица, указывающая на исходный объект. При изменении количества исходных объектов содержимое этой индексной таблицы не будет меняться синхронно, поэтому при перемещении указателя индекса назад это невозможно. будет найден для итерации объекта, поэтому в соответствии с принципом отказоустойчивости Iterator немедленно выдаст исключение java.util.ConcurrentModificationException.
Следовательно, Итератор не позволяет изменять итерируемый объект во время его работы. Но вы можете использовать собственный метод Iterator Remove() для удаления объектов. Метод Iterator.remove() удалит текущий объект итерации, сохраняя при этом согласованность индекса.
Что интересно, если ваш объект Collection/Map на самом деле имеет только один элемент, исключение ConcurrentModificationException не будет выброшено. Вот почему в javadoc указано: было бы неправильно писать программу, корректность которой зависела бы от этого исключения: ConcurrentModificationException следует использовать только для обнаружения ошибок.