2012-12-03 12 views
16

Recentemente ho sentito in una conversazione che una scrittura su un volatile innesca una barriera di memoria per ogni variabile a cui il thread ha scritto. È davvero corretto? Dal JLS, sembra che solo la variabile in questione si svuota, ma non altri. Qualcuno sa cosa è effettivamente corretto? Posso indicarmi una posizione concreta nel JLS?È una scrittura su una barriera di memoria volatile in Java

+1

La mia interpretazione del JLS è d'accordo con la vostra. – NPE

+1

possibile duplicato di [Variabili volatili e altre variabili] (http://stackoverflow.com/questions/12438464/volatile-variables-and-other-variables) – assylias

+0

Come chiarisce la risposta, non è solo la variabile dichiarata come volatile ma tutto scrive che è accaduto prima della volatile scrittura. – sjlee

risposta

1

Il riferimento Volatile variables and other variables stato corretto. Non mi ero reso conto che la transitività di happen-before è qualcosa che deve essere implementato dalla VM, non qualcosa che deriva dalla definizione. Sono ancora perplesso sul fatto che qualcosa con conseguenze di così vasta portata non sia indicato chiaramente, ma in realtà un corollario di una certa definizione. Per avvolgetelo: Supponiamo di avere 4 azioni di questo tipo:.

thread1  thread2 
a1 
a2 
       a3 
       a4 

dove a2 è una scrittura ad una variabile V volatile e A3 è una lettura dallo stesso v variabile volatili Da quanto definiton di accade -before (hb) che hb (a1, a2) e hb (a3, a4). Inoltre, per i volatili abbiamo hb (a2, a3). Segue ora dalla transitività richiesta di hb that hb (a1, a3). Quindi la scrittura e la successiva lettura della variabile volatile v funge da barriera di memoria.

16

Sì, avvierà una barriera. Puoi leggere di più here. Esistono 4 tipi, Load Load Load Store Store Store Store Load.

Per quanto riguarda la tua domanda

Dal JLS, sembra che solo la variabile in questione si svuota fuori, ma non gli altri. Qualcuno sa cosa è effettivamente corretto?

Tutte le scritture che si verificano prima di un archivio volatile sono visibili da altri thread con il predicato che gli altri thread caricano questo nuovo archivio. Tuttavia, le scritture che si verificano prima di un carico volatile possono o non possono essere viste da altri thread se non caricano il nuovo valore.

Per un esempio pratico

volatile int a =0; 
int b = 0; 

Thread-1 
b = 10; 
a = 3; 

Thread-2 
if(a == 0){ 
    // b can b 10 or 0 
} 
if(a == 3){ 
    // b is guaranteed to be 10 (according to the JMM) 
} 
+1

+1 * "con il predicato che gli altri thread caricano questo nuovo archivio" * – assylias

+4

Penso che il tuo esempio sia sbagliato. Thread-2 non ha bisogno di confrontare 'a' a 3 per vedere il nuovo valore di' b', è sufficiente leggere 'a'. Quindi immediatamente dopo la prima riga, Thread-2 è garantito per vedere 'b' uguale a 10 (in tutti i rami). Tuttavia, un terzo thread che non legge mai 'a' non è garantito per vedere il nuovo valore di' b'. –

+11

@PhilippWendler Penso che il punto fosse: se a == 0, la scrittura 'a = 3' non è ancora avvenuta e b può essere qualsiasi cosa, incluso 10. se a == 3, è stato scritto' a = 3' e sei garantito di avere b == 10. – assylias

Problemi correlati