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

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

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

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

Ответы [ 4 ]

7 голосов
/ 01 сентября 2010

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

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

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

Первоначальная попытка реализовать это может выглядеть следующим образом:

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

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

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

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

0 голосов
/ 01 сентября 2010

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

0 голосов
/ 01 сентября 2010
Запись

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

...