Может ли кто-нибудь объяснить мне, когда полезно использовать MapMaker или WeakHashMaps?

Я прочитал много людей, которые действительно любят MapMaker Google Guava (Коллекции), однако я не вижу никаких хороших применений.

Я прочитал javadoc, и он говорит, что он ведет себя как ConcurrentHashMap. Он также говорит, что new MapMaker().weakKeys().makeMap() можно почти всегда использовать в качестве замены для WeakHashMap.

Однако, прочитав javadocs ConcurrentHashMap и WeakHashMap заставляет меня задаться вопросом, когда полезно использовать его? Мне кажется, что у вас нет гарантии, что все, что вы разместите на карте, будет там, или я не понял?

Ответ 1

... и это несколько точка его. Слабые ссылки полезны, если вы не хотите (или не можете позволить себе) сохранить объект неопределенно в памяти. Рассмотрим следующий прецедент: вам нужно связать информацию с классами. Теперь, поскольку вы работаете в среде, где классы могут перезагружаться (скажем, в среде Tomcat или OSGi), вы хотите, чтобы сборщик мусора мог вернуть старые версии класса, как только он сочтет это безопасным.

Первоначальная попытка реализовать это может выглядеть как

class ClassAssoc {
    private final IdentityHashMap<Class<?>,MyMetaData> cache = new ...;
}

Проблема заключается в следующем: это сохранит все классы в элементе cache навсегда (или, по крайней мере, если они не будут удалены вручную), заставляя сборщик мусора сохранять их неопределенно, включая все, что указано в классе (статический член значения, информация загрузчика класса,...)

Используя слабые ссылки, сборщик мусора может вернуть старую версию класса, как только никакие другие ссылки на него (обычно экземпляры) не существуют. С другой стороны: до тех пор, пока существуют такие ссылки, значение гарантируется также достижимым от слабого ссылочного объекта и, следовательно, является допустимым ключом в таблице кэша.

Добавьте concurrency и другие злодеяния к изображению, и вы находитесь в том, что MapMaker дополнительно также предоставляет...

Ответ 2

Дело в MapMaker заключается в том, что существует много вариантов для вида создаваемой вами карты, которая позволяет этим картам выполнять множество целей.

  • Dirk дает хороший пример использования слабых клавиш.
  • Мягкие значения полезны для кеширования, так как вы можете кэшировать значения на карте, не беспокоясь о нехватке памяти, так как система может свободно выходить из кэша, если нужна память.
  • Вы можете выбрать, чтобы записи истекали через определенное количество времени. Это также полезно для кэширования, поскольку вы можете захотеть определенные данные кэшироваться в течение определенного периода времени, прежде чем выполнять дорогостоящую операцию по его обновлению.
  • Одна из моих любимых вещей - создание компьютерной карты. В вычислительной карте используется Function<K, V> для автоматического получения значения, связанного с данным ключом, если оно еще не находится на карте. Это хорошо сочетается с мягкими значениями и/или временем истечения. После того, как запись будет выведена по карте (из-за потребности или срока действия памяти), в следующий раз, когда запрашивается значение, связанное с этим ключом, оно будет автоматически восстановлено и кэшировано на карте еще раз.

Ответ 3

Запись

A WeakHashmap будет сохранена на карте, пока кто-то (кроме карты) ссылается на запись. Если никто не хочет, чтобы карта сохраняла ссылку на запись, тогда запись может быть удалена при следующем запуске GC.

Ответ 4

ConcurrentHashMap - это Map, который можно безопасно использовать в многопоточной среде. Это лучше, чем синхронизированная версия регулярного Map, потому что concurrency означает, что для доступа к этой карте без блокировки часто доступны разные потоки.