Java ConcurentMap keySet () вопрос, когда карта модифицируется и перебирает набор ключей - PullRequest
6 голосов
/ 27 марта 2009

Быстрый фон У меня есть параллельная карта, которую я использовал для кэширования некоторых значений, которые меняются довольно часто (все же стоит их кэшировать в ходе тестирования). Я хочу регулярно выгружать элементы из своего кэша, проверяя время истечения в значении. Я использую метод keySet () для получения ссылки на все мои ключи, а затем проверяю значения и, если срок их действия истек, я их удаляю. В других потоках кэш постоянно запрашивается и обновляется (удаляется).

В javadocs для keySet () было упомянуто, если карта меняется, когда я перебираю набор ключей. Установить результаты не определены. Очевидно, я хотел бы иметь определенный способ борьбы с этим, чтобы результаты были действительными. Было бы достаточно передать набор в HashSet, а затем выполнить итерацию по этому набору, поскольку, насколько я понимаю, этот набор не будет поддерживаться картой, является ли это расточительным способом памяти? Любые идеи приветствуются.

К сожалению, мой evictor - не единственный способ удаления элементов из параллельной карты, поэтому я прав, говоря, что мне нужно скопировать набор ключей в другой набор перед его повторением.

Заранее спасибо

РЕДАКТИРОВАТЬ: Оказывается, я читал Javadocs для метода Map keySet () вместо ConcurrentMap keySet (). Спасибо, мой плохой:)

Возвращает установленный вид клавиш содержится в этой карте. Набор опираясь на карту, поэтому изменения в карта отражается в наборе, и наоборот. Если карта изменена в то время как итерация по множеству находится в прогресс (кроме как через собственная операция удаления итератора), Результаты итерации не определено. Набор поддерживает элемент удаление, которое удаляет соответствующее отображение с карты, через Iterator.remove, Set.remove, удалить все сохранить все и очистить операции. Это не поддерживает операции добавления или добавления всех.

Ответы [ 2 ]

6 голосов
/ 27 марта 2009

Используете ли вы Java Concurrent HashMap ? Из документации keySet () он ведет себя так, как вы считаете полезным.

Возвращает установленный вид ключей, содержащихся на этой карте. Набор опирается на карту, поэтому изменения в карте отражаются в наборе, и наоборот. Набор поддерживает удаление элементов, которое удаляет соответствующее отображение из этой карты с помощью операций Iterator.remove, Set.remove, removeAll, retainAll и clear. Он не поддерживает операции add или addAll. Возвращенный итератор представления является «слабосогласованным» итератором, который никогда не вызовет исключение ConcurrentModificationException и гарантирует прохождение элементов в том виде, в каком они существовали при построении итератора, и может (но не гарантируется) отражать любые модификации, следующие после построения.

т.е. Вы можете удалить вещи, и все будет в порядке.

Если вы не используете эту реализацию, то что вы используете (и почему? Не смешно, но было бы интересно узнать, почему вы сделали этот выбор)

0 голосов
/ 27 марта 2009

Если кэш LRU достаточно хорошо подходит для вас, посмотрите LinkedHashMap - это делает реализацию кэша LRU тривиальной, а затем вы можете сделать результаты потокобезопасными, заключив их в вызов Collections.synchronizedMap .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...