Domanda

Vorrei mettere in cache una certa IO con l'aiuto di ConcurrentHashMap. La modifica del file binario deve essere riflessa nella cache pure. Poiché la cache sta per essere utilizzata da più thread tutte le operazioni di IO sono sincronizzate. Modifiche di carta vanno all'interno dello stesso blocco synchronized. Che si presenta più o meno come:

synchronized (file) {
    file.deleteRecord(index)
    map.remove(index);
}

e

synchronized(file) {
    file.writeRecord(index, record);
    map.put(index, record);
}

Sia map e file sono private e non si vedono da fuori cache di classe.

è thread-sicurezza preservata se la cache legge, vale a dire map.get(index), andare senza il blocco synchronized?

Come ho detto prima, ConcurrentHashMap viene utilizzato come mappa implementazione.

È stato utile?

Soluzione

Yup. Questo è fondamentalmente il punto di ConcurrentHashMap. Da la documentazione :

  

operazioni di recupero (compreso get)   generalmente non bloccare, così possono sovrapporsi   con operazioni di aggiornamento (compresi put   e rimuovere). Recuperi riflettono la   risultati della più recente completato   operazioni di aggiornamento della holding alla loro   insorgenza.

e dal :

  

Una raccolta simultanea è   thread-safe, ma non governato da un   serratura esclusione singolo. Nel   particolare caso di ConcurrentHashMap,   permette in modo sicuro qualsiasi numero di   concomitante legge così come un sintonizzabile   numero di scritture contemporanee.

(Sia di quelle pagine di documentazione hanno molto più dettagliato, naturalmente. Sono la pena di leggere con attenzione.)

Altri suggerimenti

Sì, filo di sicurezza è conservato fino ai riferimenti cartografici, grazie all'implementazione ConcurrentHashMap.

Gli oggetti archiviati nella mappa sono un'altra storia.

Sì, ConcurrentHashMap è thread-safe, in modo da leggere (o scrivere) non richiede alcun blocco da parte vostra.

Tuttavia, nel tuo esempio, si potrebbe finire con la seguente sequenza di eventi:

file.deleteRecord(index);
map.get(index) // returns the mapping for index even though it has been deleted from file
map.remove(index);

(lo stesso per writeRecord / put). Questo potrebbe o non potrebbe essere un problema nel tuo caso.

Bene, come tutti qui dice, questo è thread-safe in che avete un accade-prima di relazione tra la scrittura per la cache e la lettura dalla cache, ma che può essere privo di significato a seconda di ciò che altre garanzie che si spera per.

Per esempio, a meno che non fsync il file non c'è alcuna garanzia che il record sarà scritto su disco, quindi non si può leggere il record dal disco (a seconda del file system e un paio di altri fattori). Non c'è inoltre accade-prima rapporto tra il writeRecord / deleteRecord e carta di scrittura e di lettura dalla mappa, in modo che il JMM non garantisce che leggete qualcosa dalla mappa che è stata definitivamente scritta il file.

È possibile prendere una garanzia che lo stato delle index e record oggetti come scritto sarà quello che verrà letto, anche se uno di questi sono mutabili, allora questo può essere una garanzia abbastanza inutile.

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