In other words, can I do something with a volatile variable that could not also be solved with a normal variable and the Interlocked class?
For Java, “volatile” tells the compiler that the value of a variable must never be cached as its value may change outside of the scope of the program itself.
Some drawbacksThe semantics of volatile is not as strong as locking and hence might not provide atomicity. It might cause thread contention which is basically the concurrent of a resource by multiple threads. Code is a bit more complicated than normal locks.
The volatile keyword is intended to prevent the compiler from applying any optimizations on objects that can change in ways that cannot be determined by the compiler. Objects declared as volatile are omitted from optimization because their values can be changed by code outside the scope of current code at any time.
The volatile keyword indicates that a field might be modified by multiple threads that are executing at the same time. The compiler, the runtime system, and even hardware may rearrange reads and writes to memory locations for performance reasons.
EDIT: question largely rewritten
To answer this question, I dived a bit further in the matter and found out a few things about volatile
and Interlocked
that I wasn't aware of. Let's clear that out, not only for me, but for this discussion and other people reading up on this:
volatile
read/write are supposed to be immune to reordering. This only means reading and writing, it does not mean any other action;Interlocked
uses atomic assembly instructions for CompareExchange (cmpxchg
), Increment (inc
) etc;Interlocked
does use a lock sometimes: a hardware lock on multi processor systems; in uni-processor systems, there is no hardware lock;Interlocked
is different from volatile
in that it uses a full fence, where volatile uses a half fence.volatile
. It can't happen with Interlocked
. VolatileRead
and VolatileWrite
have the same reordering issue as `volatile (link thanks to Brian Gideon).Now that we have the rules, we can define an answer to your question:
volatile
that you cannot do with Interlocked
:
a = b
where a
or b
is volatile, but this is obvious;Interlocked
. In other words: you can be less safe with volatile
then you can be with Interlocked
.volatile
is faster then Interlocked
.Semantically: no, because Interlocked
simply provides a superset of operations and is safer to use because it applies full fencing. You can't do anything with volatile
that you cannot do with Interlocked
and you can do a lot with Interlocked
that you cannot do with volatile:
static volatile int x = 0;
x++; // non-atomic
static int y = 0;
Interlocked.Increment(y); // atomic
Scope: yes, declaring a variable volatile
makes it volatile for every single access. It is impossible to force this behavior any other way, hence volatile
cannot be replaced with Interlocked
. This is needed in scenarios where other libraries, interfaces or hardware can access your variable and update it anytime, or need the most recent version.
If you'd ask me, this last bit is the actual real need for volatile
and may make it ideal where two processes share memory and need to read or write without locking. Declaring a variable as volatile
is much safer in this context then forcing all programmers to use Interlocked
(which you cannot force by the compiler).
EDIT: The following quote was part of my original answer, I'll leave it in ;-)
A quote from the the C# Programming Language standard:
For nonvolatile fields,optimization techniques that consider that reorder instructions can lead to unexpected and unpredictable results in multithreaded programs that access fields without synchronization such as that provided by the lock-statement. These optimizationscan be performed by the compiler, by the runtime system, or by hardware. For volatile fields, such reordering optimizations are restricted:
A read of a volatile field is called a volatile read. A volatile read has :acquire semantics"; that is, it is guaranteed to occur prior to any references to memory that occur after it in the instruction sequence.
A write of a volatile field is called a volatile write. A volatile write has "release semantics"; that is, it is guaranteed to happen after any memory references prior to the write instruction in the instruction sequence.
Update: question largely rewritten, corrected my original response and added a "real" answer
This is a fairly complex topic. I find Joseph Albahari's writeup to be one of the more definitive and accurate sources for multithreading concepts in the .NET Framework that might help answer your question.
But, to quickly summarizes there is a lot of overlap between the volatile
keyword and the Interlocked
class as far as how they can be used. And of course both go way above and beyond what you can do with a normal variable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With