Java seems to support volatile fields of type long, while C# does not - What are the reasons behind this?

StackOverflow https://stackoverflow.com/questions/967124

Question

Can anyone explain to me what the benefits and and drawbacks of the two different approaches are?

Was it helpful?

Solution

When a double or long in Java is volatile, §17.7 of the Java Language Specification requires that they are read and written atomically. When they are not volatile, they can be written in multiple operations. This can result, for example, in the upper 32 bits of a long containing a new value, while the lower 32 bits still contain the old value.

Atomic reads and writes are easier for a programmer to reason about and write correct code with. However, support for atomic operations might impose a burden on VM implementers in some environments.

OTHER TIPS

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.

I 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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top