Несколько потоков, использующих iterator.remove () в одной коллекции, возвращают отказоустойчивый итератор

Oracle говорит

Обратите внимание, что Iterator.remove - единственный безопасный способ изменить коллекцию во время итерации; поведение не определено, если базовая коллекция изменена каким-либо другим образом во время итерации.

Может ли это означать, что даже если несколько потоков выполняют итерацию вместе над одной и той же отказоустойчивой реализацией одной коллекции, объект (_1 _, _ 2 _, _ 3 _, _ 4_) выполняет итератор . remove () не было бы заброшено ConcurrentModificationException?


person Aakash Verma    schedule 05.07.2016    source источник
comment
Нет. За исключением вектора, это, скорее всего, произойдет с несколькими потоками.   -  person Adam Gent    schedule 05.07.2016
comment
Нет. Нет. Если несколько потоков выполняют итерацию над отказоустойчивой реализацией одной и той же коллекции, будет ConcurrentModificationException, Обычно не допускается, чтобы один поток изменял коллекцию, в то время как другой поток выполняет итерацию по ней.   -  person Mihir    schedule 05.07.2016
comment
@Mihir Немного ясности. Что, если модификация iterator.remove () выполняется одним потоком, когда он проходит, а другой поток выполняет то же самое, повторяя во время итерации предыдущего потока?   -  person Aakash Verma    schedule 06.07.2016


Ответы (2)


Нет. Это говорит о том, что единственный безопасный способ удалить элементы во время итерации (в одном потоке) - использовать iterator.remove. И если к коллекции обращаются (повторяются или изменяются) из других потоков - иногда вы получите исключение, а иногда нет - в целом поведение не является детерминированным, поэтому вам следует избегать его использования или полагаться на него.

При этом единственным исключением являются параллельные коллекции.

person river    schedule 05.07.2016
comment
Таким образом, вы имеете в виду, что параллельные коллекции не сталкиваются с проблемой одновременного выполнения iterator.remove () несколькими потоками (или, если на то пошло, в любое время, когда все итераторы находятся в движении в цикле), т. Е. мы не получаем ConcurrentModificationException? - person Aakash Verma; 06.07.2016
comment
Совершенно верно, но это не решение проблемы, это сделано намеренно. Например. ConcurrentHashMap будет выполнять итерацию одновременно, и вы увидите некоторые изменения, внесенные другими потоками (вставки и удаления) - и в документе говорится, что он не потерпит неудачу с ConcurrentModificationException. Другие коллекции имеют другую семантику. - person river; 06.07.2016

Это не означает, что несколько потоков могут удалять данные с помощью iterator.remove ().

Если вы хотите добиться этого, вам нужно использовать синхронизированный тип коллекций. Даже в этом случае не следует пытаться использовать один и тот же итератор в двух потоках. Если у вас есть два потока, которым необходимо удалить запись, тогда каждый из них должен иметь свои собственные итераторы.

person sauumum    schedule 05.07.2016
comment
Что, если у них есть свои собственные, и они повторяются в течение одного и того же временного интервала? Думаю, вы не поняли мой вопрос. Позвольте мне перефразировать. Если два или более потоков, имеющих свои собственные индивидуальные итераторы, выполнят iterator.remove () в один и тот же момент или в любое время, в течение которого каждый из этих итераторов просматривает свои коллекции вместе, будет это причина ConcurrentModificationException? - person Aakash Verma; 06.07.2016