Может ли кто-нибудь объяснить мне, когда полезно использовать 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 означает, что для доступа к этой карте без блокировки часто доступны разные потоки.