2009-06-08 2 views

risposta

8

Quando un double o long in Java è volatile, §17.7 of the Java Language Specification richiede che vengano letti e scritti atomicamente. Quando non sono volatili, possono essere scritti in più operazioni. Ciò può risultare, ad esempio, nei 32 bit superiori di un lungo contenente un nuovo valore, mentre i 32 bit inferiori contengono ancora il vecchio valore.

Le letture e le scritture atomiche sono più semplici per un programmatore con cui ragionare e scrivere codice corretto con. Tuttavia, il supporto per le operazioni atomiche potrebbe imporre un onere agli implementatori VM in alcuni ambienti.

5

Immagino che si tratti di ciò che il modello di memoria può garantire. Non conosco una grande quantità del modello di memoria CLI (che C# deve usare), ma so che garantirà 32 bit ... ma non 64 (anche se garantirà un riferimento a 64 bit su x64 - le regole complete si trovano al §17.4.3 dell'ECMA 334v4). Quindi non può essere volatile. Hai comunque i metodi Interlocked, ad esempio (come long Interlocked.Exchange(ref long,long) e long Interlocked.Increment(ref long) ecc.).

+0

Tuttavia, è strano che il codice non ti consenta di specificare un campo volatile a 64 bit quando specifichi anche che la piattaforma sia x64. –

+3

La CLI dovrebbe funzionare indipendentemente dalla piattaforma sottostante, quindi non vuole fare promesse che dipendono da ciò su cui si sta eseguendo. –

0

Suppongo che i long non possano essere volatili in C# perché sono più grandi di 32 bit e non è possibile accedervi in ​​un'operazione atomica. Anche se non sarebbero memorizzati in un registro o nella cache della CPU, poiché è necessario più di un'operazione per leggere o scrivere il valore, è possibile che un thread legga il valore mentre un altro è in fase di scrittura.

Credo che ci sia una differenza tra il modo in cui Java implementa i campi volatili e come funziona DotNet, ma non sono sicuro dei dettagli. Java potrebbe utilizzare un blocco sul campo per prevenire il problema che ha C#.

7

Non conosco il motivo per cui volatile non può essere applicato a 64-bit ints in C#, ma è possibile utilizzare Thread.VolatileWrite per fare ciò che si desidera in C#. La parola chiave volatile è solo zucchero sintattico per questa chiamata.

estratto:

Nota: In C#, utilizzando il modificatore volatile, su un campo garantisce che tutti gli accessi a quel campo utilizza Thread.VolatileRead o Thread.VolatileWrite.

Lo zucchero sintattico (parola chiave) si applica a 32 bit int, ma è possibile utilizzare le chiamate di metodo effettive su 64 bit inte.