2010-04-22 18 views
8

Contrassegnare una variabile come volatile in Java assicura che ogni thread visualizzi il valore che è stato scritto su di esso anziché un valore scaduto. Mi stavo chiedendo come questo sia stato effettivamente raggiunto. La JVM emette istruzioni speciali per lo svuotamento della CPU o qualcosa del genere?Come funziona davvero volatile?

+0

questione connessa (il primo della lista in realtà ..) http://stackoverflow.com/questions/1787450/how-do- i-understand-read-memory-barriers-and-volatile – BalusC

+0

E un thread che ho iniziato su volatile con molti "upvotes" e "preferiti" relativi all'esecuzione fuori ordine: http://stackoverflow.com/questions/2441279/java-volatile-guarantee-and-out-of-order-execution – SyntaxT3rr0r

risposta

8

Da quello che ho capito sembra sempre che la cache sia stata svuotata dopo la scrittura, e appare sempre come se le letture venissero eseguite direttamente dalla memoria in lettura. L'effetto è che un thread vedrà sempre i risultati delle scritture da un altro thread e (secondo il modello di memoria Java) mai un valore memorizzato nella cache. L'effettiva implementazione e le istruzioni della CPU varieranno comunque da un'architettura all'altra.

Non garantisce la correttezza se si incrementa la variabile in più di un thread, oppure si controlla il suo valore e si agisce perché ovviamente non esiste alcuna sincronizzazione effettiva. In genere, è possibile garantire l'esecuzione corretta solo se nella variabile è presente solo la scrittura di Thread e gli altri stanno tutti leggendo.

Si noti inoltre che una variabile NON volatile a 64 bit può essere letta/scritta come due variabili a 32 bit, quindi le variabili a 32 bit sono atomiche in scrittura ma quelle a 64 bit no. Una metà può essere scritta prima di un'altra - quindi il valore letto potrebbe essere inferiore al vecchio o al nuovo valore.

Questo è piuttosto utile pagina dai miei preferiti:

http://www.cs.umd.edu/~pugh/java/memoryModel/

+2

@jgubby: il tuo ultimo paragrafo non sembra corretto: non puoi leggere un volatile a 64 bit che avrebbe 32 bit da una scrittura e l'altro da 32 bit da un'altra scrittura. – SyntaxT3rr0r

+1

@WizardOfOdds: concordato. Significa dire variabile NON-volatile lì. – gubby

+0

@jbuggy: ah ah, questo è quello che pensavo ma non ho osato modificare il tuo post perché non ero sicuro di cosa volevi dire :) Sono contento di aiutarti, perché altrimenti è stato un po 'confuso :))) – SyntaxT3rr0r

1

Esattamente ciò che accade è specifico del processore. Generalmente ci sono alcune istruzioni sulla barriera della memoria. Flushing dell'intera cache sarebbe ovviamente molto costoso - ci sono protocolli di coerenza della cache nell'hardware.

È inoltre importante che alcune ottimizzazioni non vengano eseguite attraverso gli accessi al campo. Il compilatore è importante quando si considera il multithreading, non pensare solo all'hardware.

+1

Esattamente ciò che accade in un programma Java scritto correttamente non è specifico del processore. – gubby

+0

@jgubby La domanda chiede se vengono emesse istruzioni speciali. –

Problemi correlati