Я хотел бы использовать ConcurrentHashMap, чтобы один поток удалял некоторые элементы с карты периодически и другие потоки, чтобы одновременно помещать и получать элементы с карты.
Я использую map.entrySet().removeIf(lambda)
в удаляемой теме. Мне интересно, какие предположения я могу сделать о его поведении. Я вижу, что метод removeIf
использует итератор для прохождения элементов на карте, проверки данного условия и последующего удаления при необходимости с помощью iterator.remove()
.
Документация дает некоторую информацию о поведении итераторов ConcurrentHashMap:
Аналогично, итераторы, разделители и перечисления возвращают элементы отражающие состояние хеш-таблицы в какой-то момент времени или после создание итератора/перечисления. эй не бросать ConcurrentModificationException. Однако итераторы предназначены для использования только по одному потоку за раз.
Поскольку весь вызов removeIf
происходит в одном потоке, я могу быть уверен, что итератор не используется более чем одним потоком в то время. Тем не менее мне интересно, возможен ли описанный ниже ход событий:
- Карта содержит отображение:
'A'->0
- Удаление темы начинается с
map.entrySet().removeIf(entry->entry.getValue()==0)
- Удаление вызовов потоков
.iteratator()
внутриremoveIf
вызывает и получает итератор, отражающий текущее состояние коллекции - Другой поток выполняет
map.put('A', 1)
- Удаление потока по-прежнему видит
'A'->0
mapping (итератор отражает старое состояние), а поскольку0==0
- true, он решает удалить ключ A с карты. - Теперь карта содержит
'A'->1
, но удаление потока увидело старое значение0
и запись'A' ->1
удалена, хотя ее не должно быть. Карта пуста.
Я могу представить, что поведение может быть предотвращено реализацией по-разному. Например: возможно, итераторы не отражают операции put/remove, но всегда отражают обновления значений или, возможно, метод удаления итератора проверяет, все ли отображение (как ключ, так и значение) все еще присутствует на карте, прежде чем вызывать удаление ключа. Я не мог найти информацию об этих вещах, и мне интересно, есть ли что-то, что делает этот сейф безопасным.