Безопасно ли использовать HashSet в качестве очень простого кэша в многопоточной среде? - PullRequest
0 голосов
/ 28 мая 2019

Я понимаю, что есть похожие вопросы / ответы на этот вопрос, но я не могу найти именно то, что ищу.

Я ищу реализацию кэша в памяти, который кэшируетрезультат обращения к БД, которая выполняет проверку существования.Эта проверка существования довольно дорогая, и как только объект существует в БД, он никогда не будет удален, поэтому все, что мне нужно, - это очень простой кэш в памяти (даже внутри процесса).Как только вызов БД сделан, процесс запоминает результат проверки существования этого идентификатора и не должен снова вызывать БД.

(Возможно, стоит упомянуть еще одну вещь, если объект не существует в БД, он будет создан).

Я использую HashSet (java) для этого и просто добавляю идентификатор в набор, когда проверка / создание завершена, однако это среда с высокой степенью одновременности, и яне уверен насчет последствий отсутствия потоков в HashSet.

Код всегда использует только методы add () и contains () (без итерации).

Меня это не особо волнуетпромах кэша (и, как следствие, дополнительный вызов БД) здесь и там, но мне интересно, может ли этот шаблон add () и contains () быть вызванным на множестве в параллельных потоках, мог привести к более катастрофическим ошибкам.

Ответы [ 2 ]

1 голос
/ 28 мая 2019

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

Set<String> myConcurrentSet = ConcurrentHashMap.newKeySet();
0 голосов
/ 28 мая 2019

Нет.Если вы хотите использовать Map в многопоточной среде, используйте Collections.synchronizedMap(<map object>) или ConcurrentHashMap.newKeySet();:

Set<String> concurrentSet = Collections.synchronizedSet(new HashSet<>());

или ...

Set<String> concurrentSet = ConcurrentHashMap.newKeySet();
...