Подтвердить что ты не робот

Неустойчивый HashMap против ConcurrentHashMap

У меня есть класс кеша, который содержит volatile HashMap<T> для хранения элементов кэша.

Мне любопытно, каковы были бы последствия изменения volatile HashMap на ConcurrentHashMap?

Могу ли я увеличить производительность? Этот кеш является кешем для чтения.

Какой вариант лучше всего использовать? просто HashMap? Кэш заполняется с интервалом.

4b9b3361

Ответ 1

Во-первых, похоже, вы не понимаете, что делает ключевое слово volatile. Он гарантирует, что если ссылочное значение, содержащееся в объявленной переменной volatile, изменится, другие потоки будут видеть это, а не кешированную копию. Это не имеет никакого отношения к безопасности потоков в отношении доступа к HashMap

Учитывая это, и тот факт, что вы говорите, что HashMap доступен только для чтения... вам, конечно, не нужно использовать ничего, что обеспечивает безопасность потоков, включая ConcurrentHashMap

Изменить для добавления: Ваше последнее редактирование теперь говорит: "Кэш заполняется с интервалом"

Что это не только для чтения, не так ли?

Если вы собираетесь читать потоки, когда вы пишете (обновляя существующий HashMap), вы должны использовать ConcurrentHashMap, да.

Если вы заполняете совершенно новый HashMap, а затем присваиваете его существующей переменной, вы используете volatile

Ответ 2

Вы говорите, что кеш доступен только для чтения, но также обновляется с интервалом, который кажется противоречивым.

Если весь кеш обновляется с интервалом, я буду продолжать использовать volatile. Волатильность будет гарантировать, что обновленная карта будет безопасно опубликована.

public final class  Cache
{
   private volatile Map<?,?> cache;

   private void mapUpdate() {
      Map<?,?> newCache = new HashMap<>();

      // populate the map

      // update the reference with an immutable collection
      cache = Collections.unmodifiableMap(newCache);
   }
}

Если обновление интервалов изменяет один и тот же кеш, то вы, вероятно, захотите использовать ConcurrentHashMap или скопировать карту, обновить копию и обновить ссылку.

public final class  Cache
{
   private volatile Map<?,?> cache;

   private void mapUpdate() {
      Map<?,?> newCache = new HashMap<>(cache);

      // update the map

      // update the reference with an immutable collection
      cache = Collections.unmodifiableMap(newCache);
   }
}