У меня есть большое количество вещей, поток, который многократно перебирает их, и отдельный поток, который время от времени удаляет или добавляет отдельные вещи. Вещи находятся в синхронизированном связанном списке:
private List<Thing> things = Collections.synchronizedList(new LinkedList<Thing>());
Мой первый поток перебирает их:
while (true) {
for (Thing thing : things) {
thing.costlyOperation();
}
// ...
}
Когда мой второй поток добавляет или удаляет что-то, приведенный выше итератор взрывается ConcurrentModificationException
. Однако кажется, что удаление и добавление допустимы в моем вышеприведенном случае. Ограничения заключаются в том, что (A) метод costlyOperation
не должен вызываться, когда вещь отсутствует в списке, и (B) должен вызываться сразу (на текущей или следующей итерации), когда вещь присутствует, и (C ) добавления и удаления через этот второй поток должны выполняться быстро, а не ждать.
Я мог бы выполнить синхронизацию на things
перед входом в итерационный цикл, но это слишком долго блокирует другой поток. В качестве альтернативы я могу изменить Thing
, чтобы включить флаг isDead
, и выполнить хороший быстрый цикл iterator.remove()
, чтобы избавиться от мертвых вещей перед циклом выше, в котором я снова проверю флаг. Но я хочу решить эту проблему рядом с циклом for с минимальным загрязнением. Я также рассматривал возможность создания копии списка (форма «отказоустойчивой итерации»), но это, похоже, нарушает ограничение A.
Потребуется ли мне кодировать мою собственную коллекцию и итератор? С нуля? Не упускаю ли я из виду, что CME на самом деле является полезным исключением даже в этом случае? Есть ли структура данных, стратегия или шаблон, который я мог бы использовать вместо итератора по умолчанию для решения этой проблемы?
costlyOperation()
и удалить элементы из очереди производителя до выполнения, если они становятся мертвыми. - person Kevin Condon   schedule 24.03.2015thing
должен быть вthings
чек, ничто другое не может гарантировать это. У @KevinCondon есть лучшее решение, если вы можете немного расслабиться, ИМО. - person Sbodd   schedule 24.03.2015