2016-02-15 16 views
6

Ho bisogno di un meccanismo di blocco per chiave per proteggere le sezioni critiche legate alle chiavi.La cache di Guava <K, Semaphore> with weakValues ​​() potrebbe essere thread safe?

Anche se un ConcurrentMap<K, Semaphore> è sufficiente per la concorrenza, non voglio nemmeno che la mappa accumuli vecchie chiavi e cresca indefinitamente.

Idealmente, la struttura dati alla fine (o subito dopo) rilascia la memoria utilizzata per le chiavi a cui i blocchi sono inutilizzati.

che sto tipo di pensiero di Guava Cache costruito con weakValues() farebbe il trucco:

private static final LoadingCache<K, Semaphore> KEY_MUTEX = CacheBuilder.newBuilder() 
     .weakValues() 
     .build(new CacheLoader<K, Semaphore>() { 
      @Override 
      public Semaphore load(K key) throws Exception { 
       return new Semaphore(1); 
      } 
     }); 

Esistono ragioni per cui questo potrebbe non fornire sufficiente controllo della concorrenza?

O ragioni per cui questo potrebbe non comportare la raccolta di dati inutili da parte di coppie non utilizzate?

risposta

3

Sì, funzionerebbe.

C'è anche una struttura dati progettata più o meno per questo caso d'uso: Striped.

+1

Si noti che 'com.google.common.util.concurrent.Striped' * non * garantisce un oggetto di sincronizzazione per chiave. Più chiavi possono condividere lo stesso oggetto e questo può ridurre la concorrenza. In quanto tale, 'Striped' può o non può essere un'opzione praticabile a seconda del caso di progettazione/uso. – antak