Domanda

Può il seguente pezzo di codice essere riscritta w / o utilizzando Collections.synchronizedMap() pur mantenendo correttezza in concorrenza?

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

vale a dire. c'è qualcosa da uno java.util.concurrent può usare invece? Si noti che la semplice sostituzione con

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

ovviamente non funzionerà

È stato utile?

Soluzione

Guava 's CacheBuilder classe ti permette di fare questo con facilità.

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

Si noti che questo cambia la semantica chiave di uguaglianza per essere == invece di .equals() che non importa in caso di utilizzo di casi Class ma è un potenziale problema.

Altri suggerimenti

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

"Come maggior parte delle classi di raccolta, questa classe non è sincronizzato. Un WeakHashMap sincronizzato può essere costruito utilizzando il metodo Collections.synchronizedMap".

Cafeine è un concorrente popolare di cache di Guava.

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

utilizzo:

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

Fa avvolgendo il WeakHashMap in una mappa sincronizzato ancora lavorare   correttamente per quello che si vuole fare, dal momento che il garbage collector può   modificare le WeakReferences direttamente in qualsiasi momento, bypassando il   sincronizzato mappa involucro? Credo WeakHashMap funziona solo veramente in un   modello filettato singola.

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

  

"A WeakHashMap sincronizzato può essere costruito utilizzando il   Metodo Collections.synchronizedMap "

Il che implica per me che questa tecnica deve lavorare in tandem con il comportamento del garbage collector (a meno che la documentazione è bacato!)

Se si utilizza Java 7 e al di sopra, questo caso l'uso è risolto in un 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 su concorrenza e leggere attentamente il documento.

Se si utilizza Java 6 o al di sotto. No, è necessario sincronizzare un WeakHashMap.

Fa avvolgendo il WeakHashMap in una mappa sincronizzata continuerà a funzionare correttamente per quello che si vuole fare, dal momento che il garbage collector può modificare i WeakReferences direttamente in qualsiasi momento, bypassando la mappa involucro sincronizzato? Credo WeakHashMap funziona solo veramente in un unico modello filettato.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top