2014-04-15 8 views
5

È molto noto tra i programmatori Java che, per il corretto funzionamento del blocco con doppia verifica, la variabile deve essere dichiarata volatile e la sincronizzazione dell'inizializzazione dell'oggetto non è sufficiente.È richiesto `volatile` per il blocco con doppio controllo in Java ma non C#?

Il consapevolezza probabilmente è soprattutto perché la semantica della parola chiave volatile sono stati cambiati nella 1.5 di includere una "avviene prima" relazione, almeno in una parte di rendere ricontrollato blocco di sicurezza; da quello che ho capito, la relazione "succede prima" significa che scrivere su una variabile volatile fa sì che tutte le variabili memorizzate nella cache nella scrittura vengano scritte nella memoria principale e, dopo aver letto una variabile volatile, tutte le variabili memorizzate nella cache sono considerate obsolete e devono essere rileggere dalla memoria principale, in modo che tutto ciò che è scritto prima di una scrittura su una variabile volatile sia garantito per "accadere prima" una lettura successiva da quella variabile.

Stack Overflow seems to believe che, per C#, volatile non è necessaria l'interblocco ricontrollato (nonostante notando la preoccupazione che questo può essere specifico per determinate CPU oa l'implementazione Microsoft), ma anche di credere che la semantica di synchronized dichiarazione di Java sono exactly the same come l'affermazione lock di C#, che suggerisce che gli stessi problemi identificati in Java esisterebbero anche per C#, a meno che non esistano altre importanti differenze nella semantica del blocco a doppio controllo tra le due lingue.

Quindi ... che è corretto? Il blocco con doppia verifica in C# è effettivamente meno pericoloso rispetto a Java? In tal caso, quale semantica linguistica differisce per rendere questo il caso?

In caso negativo, cosa può andare specificamente nello specifico senza volatile? La semantica di volatile in C# stabilisce una relazione "succede prima" come Java, in modo che il blocco a doppio controllo sia sicuro in C# con volatile come in Java a partire da 1.5?

+0

Vedere [questo] (http://blogs.msdn.com/b/ericlippert/archive/2011/06/16/atomicity-volatility-and-immutability-are-different-part-three.aspx) e [ questo] (http://stackoverflow.com/a/5821201/116614). – mellamokb

risposta

2

Da MSDN: "La parola chiave volatile indica che un campo potrebbe essere modificato da più thread che stanno eseguendo contemporaneamente Fields dichiarate volatile non sono soggetti a compilatore ottimizzazioni che assumono accesso da un unico filo Ciò garantisce.. che il valore più aggiornato è presente sul campo in ogni momento. "

Quindi, volatile è utile solo se si modifica il valore della variabile da più thread. Se blocchi() le aree di codice che accedono alle risorse condivise con lo stesso oggetto di blocco, è garantito che solo un thread può accedere a quelle aree di codice contemporaneamente, quindi volatile non è necessario a meno che tu non stia modificando l'oggetto di blocco (che è una pessima idea) .