2013-03-17 17 views
7

Ho letto che java volatile è sequenziale coerente ma non atomico. Per atomicity java fornisce una libreria diversa.Qual è la differenza tra coerenza sequenziale e atomicità?

Qualcuno può spiegare la differenza tra due, in inglese semplice?

(credo che il campo di applicazione domanda comprende C/C++ e quindi l'aggiunta di questi tag di lingua per ottenere più grande pubblico.)

+0

Non penso che 'volatile' offra la stessa garanzia in C/C++ come in Java. In particolare, non penso che fornisca in C ciò che chiamate consistenza sequenziale (cioè che la barriera di memoria si applica ad altre variabili) - TBC. – assylias

+1

@assylias non intendevo dire che volatile ha lo stesso significato in C/C++. Sono sicuro che non sia così.Mi riferivo al concetto di 'coerenza sequenziale e atomicità' che è comune tra c/C++ e Java. In C/C++ la parola chiave volatile interrompe l'ottimizzazione dell'utilizzo della variabile e non viene utilizzata per mantenere la coerenza sequenziale tra le operazioni specificate prima dell'operazione con una variabile volatile .. –

risposta

7

Immaginate queste due variabili in una classe:

int i = 0; 
volatile int v = 0; 

E quei due metodi

void write() { 
    i = 5; 
    v = 2; 
} 

void read() { 
    if (v == 2) { System.out.println(i); } 
} 

La semantica volatili garantire che read saranno sia di stampa 5 o niente (supponendo che non altri metodi stanno modificando il campi ovviamente). Se v non fosse volatile, read potrebbe anche stampare 0 perché i = 5 e v = 2 potrebbero essere stati riordinati. Immagino che questo sia ciò che intendi per consistenza sequenziale, che ha un significato più ampio.

D'altra parte, volatile non garantisce l'atomicità. Quindi, se due thread chiamano questo metodo in concomitanza (v è la stessa volatile int):

void increment() { 
    v++; 
} 

si ha alcuna garanzia che V sarà incrementato di 2. Questo perché v++ è in realtà tre affermazioni:

load v; 
increment v; 
store v; 

ea causa di interleaving di thread v potrebbe essere incrementato solo una volta (entrambi i thread caricheranno lo stesso valore).

+0

Sarebbe una risposta completa se è possibile aggiungere un esempio che dimostrerà qualcosa che è atomico e sequenziale. Possiamo farlo senza usare mutex? –

+1

Al momento non è possibile eseguire l'aggiornamento, ma sì, quindi gli algoritmi di blocco liberi vengono utilizzati dalle operazioni CAS per fornire l'atomicità. È utilizzato da tutte le classi AtomicXXX in java. – assylias

5

Supponiamo di avere queste due variabili:

public int a = 0; 
public volatile int b = 0; 

e supponiamo un thread fa

a = 1; 
b = 2; 

Se un altro thread legge questi valori e vede che b == 2, quindi è garantito per vedere anche a == 1.

Ma il thread di lettura potrebbe vedere a == 1 e b == 0, poiché le due scritture non fanno parte di un'operazione atomica, quindi il thread di lettura potrebbe vedere la modifica apportata a a prima che il primo thread abbia assegnato un valore a .

di rendere questi due scritture atomica, si avrebbe bisogno di sincronizzare l'accesso a queste due variabili:

synchronized (lock) { 
    a = 1; 
    b = 2; 
} 

... 

synchronized (lock) { 
    System.out.println("a = " + a + "; b = " + b); 
} 

E in questo caso, il filo di lettura vedrà a == 0 e b == 0, o a == 1 e b == 2, ma mai lo stato intermedio.

+2

+1, ma non si sta dicendo "questo è sequenziale coerenza "e" questa è atomicità ". – Dukeling

+0

Sì, ho pensato che fosse ovvio. Ma la risposta di assylia è più chiara e migliore della mia comunque. –

Problemi correlati