Can anyone explain to me what the benefits and and drawbacks of the two different approaches are?
views:
404answers:
4I guess it comes down to what the memory model can guarantee. I don't know a vast amount about the CLI memory model (that C# has to use), but I know it'll guarantee 32 bits... but not 64 (although it'll guarantee a 64-bit reference on x64 - the full rules are in §17.4.3 of ECMA 334v4) . So it can't be volatile
. You still have the Interlocked
methods, though (such as long Interlocked.Exchange(ref long,long)
and long Interlocked.Increment(ref long)
etc).
I'm guessing that longs can't be volatile in C# because they are larger than 32-bits and can not be accessed in an atomic operation. Even though they would not be stored in a register or CPU cache, because it takes more than one operation to read or write the value it is possible for one thread to read the value while another is in the process of writing it.
I believe that there is a difference between how Java implements volatile fields and how DotNet does, but I'm not sure on the details. Java might use a lock on the field to prevent the problem that C# has.
I don't know the reason why volatile cannot be applied to 64-bit ints in C#, but You can use Thread.VolatileWrite to do what you want in C#. The volatile keyword is just syntactic sugar on this call.
excerpt:
Note: In C#, using the volatile modifier on a field guarantees that all access to that field uses Thread.VolatileRead or Thread.VolatileWrite.
The syntactic sugar (keyword) applies to 32-bit ints, but you can use the actual method calls on 64-bit ints.