Y at-il équivalent java.util.concurrent pour WeakHashMap?
-
20-09-2019 - |
Question
le morceau de code suivant peut être réécrite w / o en utilisant la correction Collections.synchronizedMap()
maintenant encore à la concurrence?
Collections.synchronizedMap(new WeakHashMap<Class, Object>());
i.e.. est-il quelque chose d'un java.util.concurrent peut utiliser à la place? Notez que le simple remplacement par
new ConcurrentHashMap<Class, Object>(new WeakHashMap<Class, Object>()));
ne fonctionnent évidemment pas
La solution
goyave de CacheBuilder classe vous permet de le faire facilement.
CacheBuilder.newBuilder().weakKeys().build()
Notez que cela modifie la sémantique de l'égalité clés à ==
au lieu de .equals()
qui ne sera pas question dans votre cas d'utilisation des instances de Class
mais est un écueil potentiel.
Autres conseils
Je ne crois pas qu'il y ait. En fait, le javadoc suggère d'utiliser Collections.synchronizedMap ()
« Comme la plupart des classes de collection, cette classe ne sont pas synchronisées. Peut être construit un WeakHashMap synchronisé en utilisant la méthode Collections.synchronizedMap. »
Caféine est un concurrent populaire de cache goyave.
- keys automatically wrapped in weak references
- values automatically wrapped in weak or soft references
utilisation:
LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
.weakKeys()
.weakValues()
.build(key -> createExpensiveGraph(key));
N'enveloppant le WeakHashMap sur une carte synchronisée fonctionne toujours correctement pour ce que vous voulez faire, puisque le collecteur de poubelle modifier les WeakReferences directement à tout moment, en contournant le wrapper carte synchronisée? Je pense que WeakHashMap ne fonctionne vraiment dans une modèle unique fileté.
Comme mentionné ci-dessus, la documentation WeakHashMap https://docs.oracle.com/javase/7/docs/api/java/util/WeakHashMap.html dit spécifiquement:
"peut être construit de A WeakHashMap synchronisé en utilisant le méthode Collections.synchronizedMap "
Ce qui me implique que cette technique doit travailler en tandem avec le comportement du garbage collector (à moins que la documentation est buggé!)
Si vous utilisez Java 7 et au-dessus, ce cas d'utilisation est résolu d'une manière thread-safe avec ClassValue
https://docs.oracle.com/javase/7/docs/api/java/lang/ClassValue.html Si vous avez besoin de l'utilisation de remove
, réfléchir à la concomitance et lire doc à fond.
Si vous utilisez Java 6 ou ci-dessous. Non, vous devez synchroniser un WeakHashMap.
N'enveloppant le WeakHashMap sur une carte synchronisée correctement pour toujours ce que vous voulez faire, puisque le garbage collector peut modifier les WeakReferences directement à tout moment, sans passer par l'emballage de carte synchronisée? Je pense que WeakHashMap ne fonctionne vraiment dans un seul modèle fileté.