2012-05-14 6 views
7

Ho letto da qualche parte che in ConcurrentHashMap, l'intero oggetto della mappa non è bloccato e invece un blocco è fatto su una porzione della Mappa.Blocco di ConcurrentHashMap

Qualcuno può elaborare quando entra in scena il blocco?

È giusto che durante la lettura della mappa non sia coinvolto alcun blocco ma durante l'aggiornamento viene utilizzato solo il blocco?

+3

questo articolo dovrebbe aiutare: http://www.ibm.com/developerworks/java/library/j-jtp08223/ – yegor256

+1

The [javadoc] (http://docs.oracle.com/javase/7/docs/ api/java/util/concurrent/ConcurrentHashMap.html) è abbastanza dettagliato nello spiegare l'implementazione. – trutheality

risposta

12

Sì, ConcurrentHashMap utilizza una moltitudine di blocchi, ogni blocco controlla un segmento dell'hash.

Quando si impostano i dati in un particolare segmento, si ottiene il blocco per quel segmento.

Quando si ricevono i dati, viene utilizzata una lettura volatile. Se la lettura volatile provoca un errore, il blocco per il segmento viene ottenuto per un ultimo tentativo di lettura corretta.

+1

Non ho ottenuto "se la Se la lettura volatile provoca un errore, allora il blocco per il segmento viene ottenuto per un ultimo tentativo di lettura corretta". Puoi spiegare poco nei dettagli? – Anand

+1

@anand Secondo il JMM è possibile che la scrittura volatile di un campo nel costruttore possa essere visibile ai thread dopo che l'oggetto ha terminato la costruzione ed è visibile ad altri thread (questo non è vero per i campi finali). Il lucchetto a cui si riferisce assicurerà l'accadimento, prima di ordinare quella scrittura volatile su altre letture. Nota: Questo è stato in grado di accadere, tuttavia potrebbe non avere mai e ho letto in Java 6 non può mai - si parlava di rimuoverlo solo a causa di tutta la confusione. –

+2

E solo per rendere chiaro il completamento del costruttore si riferisce all'ingresso del secchio. –

5

Il blocco è ridotto al minimo il più possibile pur rimanendo sicuro per i thread.

Per spiegare "parte della mappa è bloccata", ciò significa che durante l'aggiornamento, solo un "1/concurrencyLevel" della mappa (basato su un hash della chiave) è bloccato. Ciò significa che due aggiornamenti possono essere eseguiti contemporaneamente in modo sicuro se ciascuno di essi influisce su "bucket" separati, riducendo così al minimo la contesa della serratura e massimizzando così le prestazioni.

Ancora più importante, fidatevi dell'implementazione JDK - non dovreste preoccuparvi dei dettagli di implementazione nel JDK (per prima cosa, potrebbe cambiare da versione a versione). Piuttosto, concentrati solo sulla scrittura del codice .

+0

Quando si collega Hashtable, si intende ConcurrentHashMap. La tua spiegazione non è corretta altrimenti. L'intera istanza di Hashtable è sincronizzata per qualsiasi modifica o lettura. –

+0

@JohnVint Grazie. Ho aggiornato la mia risposta. – Bohemian

+0

@trutheality Grazie. Ho corretto la mia risposta. – Bohemian

0

ConcurrentHashMap utilizza il meccanismo di blocco rientrante. ConcurrentHashMap utilizza segmenti invece di bucket e quando il nuovo record get insert lock acquisirà solo sul segmento non l'elenco completo dei segmenti. Quindi, qui l'idea chiarisce che il blocco a più livelli verrà acquisito sullo stesso.

Poiché nessun livello di concorrenza è stato impostato per l'esplicitazione, ConcurrentHashMap viene diviso in 16 segmenti. E ogni segmento funge da HashMap indipendente.

Nessun blocco applicato all'operazione di lettura in ConcurrentHashMap.