Domanda

Ho letto per la concorrenza da ieri e non conosco molte cose ... Comunque alcune cose stanno iniziando a chiarire ...
Capisco perché il doppio controllo del blocco non è sicuro (mi chiedo quale sia la propatà che la condizione rara verificarsi) ma volatile risolve il problema in 1,5 + ....
Ma mi chiedo se questo si verifica con putifAbsent

Come ...

myObj = new myObject("CodeMonkey");
cHashM.putIfAbsent("keyy",myObj);  
.

Quindi questo assicura che myObj sarebbe stato indiano al 100% quando un altro thread fa un cHashM.get() ???Poiché potrebbe avere un riferimento ISNT completamente inizializzato (il problema del blocco a doppio controllo)

È stato utile?

Soluzione

Se si invoca concurrentHashMap.get(key) e restituisce un oggetto, tale oggetto è garantito per essere completamente inizializzato.Ogni inserimento (o putifabsent) otterrà un blocco specifico del secchio e aggiungerà l'elemento alle voci del secchio.

Ora puoi passare attraverso il codice e notare che il metodo Get non ottiene questo stesso blocco.Quindi puoi discutere che ci può essere una lettura obsoleta, non è nemmeno vera.La ragione qui è che il valore all'interno della voce stessa è volatile.Quindi sarai sicuro di ottenere la lettura più aggiornata.

Altri suggerimenti

Il metodo putIfAbsent in ConcurrentHashMap è il metodo check-IF-assente-quindi impostato.È un'operazione atomica.Ma per rispondere alla parte seguente: "Quindi questo assicura che MyOBJ sarebbe stato indiano al 100% quando un altro thread fa un chashm.get ()", dipenderebbe da quando l'oggetto viene inserito nell'HashMap.Di solito c'è una precedenza successiva, I.e., Se il chiamante viene prima che l'oggetto venga posizionato nella mappa, allora null verrà restituito, altrimenti il valore verrà restituito.

La parte rilevante della documentazione è questa:

.

Effetti di consistenza della memoria: come con Altre collezioni simultanee, azioni in un thread prima di posizionare un oggetto in un concordrentmap come chiave o valore accadere, prima delle azioni successive a l'accesso o la rimozione di quell'oggetto dal concubito in un altro Discussione.

- java.util.ConcurrentMap .

Allora, sì, hai il tuo è presente-prima relazione.

Non sono un esperto in questo, ma guardando l'implementazione di Segment in ConcurrentHashMap Vedo che il campo volatile count sembra essere utilizzato per garantire una corretta visibilità tra i fili.Tutte le operazioni di lettura devono leggere il campo count e tutte le operazioni di scrittura devono scrivere ad esso.Dai commenti nella classe:

Read operations can thus proceed without locking, but rely
on selected uses of volatiles to ensure that completed
write operations performed by other threads are
noticed. For most purposes, the "count" field, tracking the
number of elements, serves as that volatile variable
ensuring visibility.  This is convenient because this field
needs to be read in many read operations anyway:

   - All (unsynchronized) read operations must first read the
     "count" field, and should not look at table entries if
     it is 0.

   - All (synchronized) write operations should write to
     the "count" field after structurally changing any bin.
     The operations must not take any action that could even
     momentarily cause a concurrent read operation to see
     inconsistent data. This is made easier by the nature of
     the read operations in Map. For example, no operation
     can reveal that the table has grown but the threshold
     has not yet been updated, so there are no atomicity
     requirements for this with respect to reads.
.

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