Есть ли эквивалент java.util.concurrent для WeakHashMap?
Можно ли переписать следующий фрагмент кода без использования Collections.synchronizedMap()
, но сохраняя правильность в concurrency?
Collections.synchronizedMap(new WeakHashMap<Class, Object>());
то есть. есть что-то из java.util.concurrent, который можно использовать вместо этого? Обратите внимание, что просто заменяя
new ConcurrentHashMap<Class, Object>(new WeakHashMap<Class, Object>()));
очевидно, не будет работать
Ответы
Ответ 1
Guava CacheBuilder class позволяет вам сделать это легко.
CacheBuilder.newBuilder().weakKeys().build()
Обратите внимание, что это изменяет семантику равенства ключей как ==
вместо .equals()
, что не имеет значения в случае использования экземпляров Class
, но является потенциальной ошибкой.
Ответ 2
Я не верю, что есть. На самом деле javadoc предлагает использовать Collections.synchronizedMap()
"Как и большинство классов коллекций, этот класс не синхронизирован. Синхронизированный файл WeakHashMap может быть создан с использованием метода Collections.synchronizedMap."
Ответ 3
Cafeine является популярным конкурентом кэш-памяти Guava.
- keys automatically wrapped in weak references
- values automatically wrapped in weak or soft references
использование:
LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
.weakKeys()
.weakValues()
.build(key -> createExpensiveGraph(key));
Ответ 4
Удерживает ли оболочка WeakHashMap синхронизированную карту правильно для того, что вы хотите сделать, поскольку сборщик мусора может изменять слабые ссылки непосредственно в любое время, обходя синхронизированная оболочка карты? Я думаю, что WeakHashMap действительно работает в однопоточная модель.
Как упоминалось выше, документация для WeakHashMap в https://docs.oracle.com/javase/7/docs/api/java/util/WeakHashMap.html специально говорит:
"Синхронизированная карта WeakHashMap может быть построена с использованием Метод Collections.synchronizedMap"
Это означает, что этот метод должен работать в тандеме с поведением сборщика мусора (если документация не глючит!)
Ответ 5
Если вы используете Java 7 и выше, этот вариант использования решается поточно- ClassValue
способом с помощью ClassValue
https://docs.oracle.com/javase/7/docs/api/java/lang/ClassValue.html Если вам требуется Использование remove
, тщательно продумать параллелизм и внимательно прочитать документ.
Если вы используете Java 6 или ниже. Нет, вы должны синхронизировать WeakHashMap.
Ответ 6
Ли оболочка WeakHashMap в синхронизированной карте все еще работает правильно для того, что вы хотите сделать, поскольку сборщик мусора может в любой момент изменить слабые ссылки в обход обмороченной карты карт? Я думаю, что WeakHashMap действительно работает только в одной многопоточной модели.