Безопасен ли этот поток, когда я использую concurrentHashMap для кэширования результата в executorCompletionService?
* * * * * * * * * * * * * * * * * * * * * * * * * * является поточно-ориентированным, как следует из его названия («Concurrent»)Однако это не означает, что код, который его использует, является потокобезопасным.
Например, если ваш код выполняет следующие действия:
SomeObject object = cacheRingMap.get(someKey); //get from cache
if (object == null){ //oh-oh, cache miss
object = getObjectFromDb(someKey); //get from the db
cacheRingMap.put(someKey, object); //put in cache for next time
}
Поскольку get
и put
не выполняются атомарно в этом примере, два потока, выполняющие этот код, могут в конечном итоге оба искать один и тот же ключ сначала в кеше, а затем в БД. Он по-прежнему поточно-ориентирован, но мы выполнили два просмотра БД вместо одного. Но это всего лишь простой пример, более сложная логика кэширования (скажем, такая, которая включает в себя аннулирование кэша и удаление из карты кэша) может оказаться не просто бесполезной, но и фактически неверной. Все зависит от того, как карта используется и что гарантирует вам от нее. Я предлагаю вам прочитать ConcurrentHashMap javadoc . Посмотрите, что он может гарантировать, а что нет.
Будет ли он работать быстро после того, как я изменюсь?
Это зависит от слишком большого количества параметров, которые необходимо знать заранее. Как база данных будет обрабатывать параллельные запросы? Сколько запросов есть? Как быстро выполняется один запрос? И т.д. Лучший способ узнать это на самом деле попробовать.
В качестве примечания: если вы ищете способы повышения производительности, вы можете попробовать использовать пакетный запрос. Тогда потоком будет поиск в кеше всех необходимых вам ключей, сбор ключей, которые нужно найти, а затем отправка их всех вместе в одном запросе к базе данных. Во многих случаях один большой запрос будет выполняться быстрее, чем куча меньших.
Кроме того, вы должны проверить, быстрее ли в вашем случае одновременные поиски на карте, чем однопоточные. Возможно, распараллеливание только самого запроса, а не поиска в кэше, может дать лучшие результаты в вашем случае.