Esiste l’equivalente java.util.concurrent per WeakHashMap?

Il seguente pezzo di codice può essere riscritto senza utilizzare Collections.synchronizedMap() mantenendo la correttezza alla concorrenza?

 Collections.synchronizedMap(new WeakHashMap()); 

cioè c’è qualcosa da java.util.concurrent che si può usare invece? Si noti che semplicemente sostituendo con

 new ConcurrentHashMap(new WeakHashMap())); 

ovviamente non funzionerà

La class CacheBuilder di Guava ti consente di farlo facilmente.

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

Si noti che questo cambia la semantica della chiave dell’uguaglianza a essere == invece di .equals() che non ha importanza nel caso di utilizzo di istanze di Class ma è una potenziale trappola.

Non credo che ci sia. Infatti javadoc suggerisce di usare Collections.synchronizedMap ()

“Come la maggior parte delle classi di raccolta, questa class non è sincronizzata: una WeakHashMap sincronizzata può essere costruita usando il metodo Collections.synchronizedMap.”

Cafeine è un popolare concorrente del cache Guava.

 - keys automatically wrapped in weak references - values automatically wrapped in weak or soft references 

utilizzo:

 LoadingCache graphs = Caffeine.newBuilder() .weakKeys() .weakValues() .build(key -> createExpensiveGraph(key)); 

Il wrapping di WeakHashMap in una mappa sincronizzata funziona ancora correttamente per ciò che si vuole fare, dal momento che il garbage collector può modificare direttamente le weakreferences in qualsiasi momento, ignorando il wrapper della mappa sincronizzato? Penso che WeakHashMap funzioni davvero solo in un singolo modello a thread.

Come accennato in precedenza, la documentazione di WeakHashMap su https://docs.oracle.com/javase/7/docs/api/java/util/WeakHashMap.html dice espressamente:

“Una WeakHashMap sincronizzata può essere costruita usando il metodo Collections.synchronizedMap”

Il che implica che questa tecnica deve funzionare in tandem con il comportamento del garbage collector (a meno che la documentazione non sia buggata!)

Se si utilizza Java 7 e versioni successive, questo caso d’uso viene risolto in modo thread-safe con ClassValue https://docs.oracle.com/javase/7/docs/api/java/lang/ClassValue.html Se si richiede l’uso di remove , riflettere attentamente sulla concorrenza e leggere attentamente il documento.

Se stai usando Java 6 o versioni successive. No, devi sincronizzare una WeakHashMap.

Il wrapping di WeakHashMap in una mappa sincronizzata funziona ancora correttamente per ciò che si vuole fare, dal momento che il garbage collector può modificare direttamente le weakreferences in qualsiasi momento, ignorando il wrapper della mappa sincronizzato? Penso che WeakHashMap funzioni davvero solo in un singolo modello a thread.