Неустойчивый HashMap против ConcurrentHashMap
У меня есть класс кеша, который содержит volatile HashMap<T>
для хранения элементов кэша.
Мне любопытно, каковы были бы последствия изменения volatile HashMap
на ConcurrentHashMap
?
Могу ли я увеличить производительность? Этот кеш является кешем для чтения.
Какой вариант лучше всего использовать? просто HashMap? Кэш заполняется с интервалом.
Ответы
Ответ 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);
}
}