Вопрос

Можно ли переписать следующий фрагмент кода без использования Collections.synchronizedMap() все же сохраняя корректность при параллелизме?

Collections.synchronizedMap(new WeakHashMap<Class, Object>());

т. е.есть ли что-нибудь из java.util.concurrent, что можно использовать вместо этого?Обратите внимание, что простая замена на

new ConcurrentHashMap<Class, Object>(new WeakHashMap<Class, Object>()));

очевидно, что это не сработает

Это было полезно?

Решение

Гуава's Конструктор кэша класс позволяет вам сделать это легко.

CacheBuilder.newBuilder().weakKeys().build()

Обратите внимание, что это изменяет семантику равенства ключей на == вместо того , чтобы .equals() что не будет иметь значения в вашем случае использования Class экземпляры, но это потенциальная ловушка.

Другие советы

Я не верю, что это так.На самом деле javadoc предлагает использовать коллекции.synchronizedMap()

"Как и большинство классов коллекции, этот класс не синхронизирован.Синхронизированная WeakHashMap может быть создана с использованием Collections.Метод synchronizedMap."

Кофеин является популярным конкурентом Guava cache.

- 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));

Работает ли по-прежнему перенос WeakHashMap в синхронизированную карту правильно для того, что вы хотите сделать, поскольку сборщик мусора может изменять weakreferences напрямую в любое время, минуя оболочку синхронизированной карты?Я думаю, что WeakHashMap действительно работает только в однопоточной модели.

Как упоминалось выше, документация для WeakHashMap на https://docs.oracle.com/javase/7/docs/api/java/util/WeakHashMap.html конкретно говорится:

"Синхронизированная WeakHashMap может быть создана с использованием Collections.Метод synchronizedMap"

Что подразумевает для меня, что этот метод должен работать в тандеме с поведением сборщика мусора (если только документация не содержит ошибок!)

Если вы используете Java 7 и выше, этот вариант использования решается потокобезопасным способом с ClassValue https://docs.oracle.com/javase/7/docs/api/java/lang/ClassValue.html Если вам требуется использование remove, тщательно подумайте о параллелизме и внимательно прочитайте документ.

Если вы используете Java 6 или ниже.Нет, вы должны синхронизировать WeakHashMap.

По-прежнему ли обертывание WeakHashMap в синхронизированную карту работает корректно для того, что вы хотите сделать, поскольку сборщик мусора может изменять weakreferences напрямую в любое время, минуя оболочку синхронизированной карты?Я думаю, что WeakHashMap действительно работает только в однопоточной модели.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top