Common usage of the volatile modifier is when a particular field is accessed by many threads without using the lock statement to serialize access.
So in essence the volatile modifier guarantees that a thread will retrieve the most recent value written by another thread (even if it was modified by the previous instruction from where you called).
Whenever a volatile is requested, the system returns the current value at the time of the request.
Similarly, All assignments are written to the object immediately.
You are not allowed to use volatile on just any time. The following is a list of types you can implement this modifier on:
- Any reference type.
- Any pointer type in a unsafe context
- sbyte, byte, short, ushort, int, uint, char, float, bool.
- An enum type with an enum base type of the following: byte, sbyte, short, ushort, int, uint.
| || |
public volatile int iAge;
Another Important Example
| || |
static bool endIsNigh = false;
static bool repented = false;
new Thread(Wait).Start(); // Start up the spinning waiter
Thread.Sleep(1000); // Give it a second to warm up!
repented = true;
endIsNigh = true;
static void Wait()
// Keep Spinning
Console.WriteLine("Gone, " + repented);
Let’s understand the usage of ‘Volatile’ by this example. Consider two possiblilities from the above example.
- Is it possible for the Wait method to continue spinning in its while loop, even after the endIsNigh flag has been set to true?
- Furthermore, is it possible for the Wait method to write "Gone, false"?
The answer to both questions is, theoretically, yes, on a multi-processor machine, if the thread scheduler assigns the two threads different CPUs.
The repented and endIsNigh fields can be cached in CPU registers to improve performance, with a potential delay before their updated values are written back to memory.
And when the CPU registers are written back to memory, it’s not necessarily in the order they were originally updated. This can result in two scenarios possible.
This caching can be circumvented by using the static methods Thread.VolatileRead and Thread.VolatileWrite to read and write to the fields. VolatileRead means “read the latest value”; VolatileWrite means “write immediately to memory”. The same functionality can be achieved more elegantly by declaring the field with the volatile modifier.
| || |
volatilestatic bool endIsNigh = false;
volatile static bool repented = false;
// Same code as above
Hope this helps.
Thanks & Regards,
Arun Manglick || Senior Tech Lead