What is the volatile keyword used for?
For both C# and 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. The compiler will then avoid any optimisations that may result in problems if the variable changes "outside of its control".
What is the volatile keyword useful for?
volatile
has semantics for memory visibility. Basically, the value of a volatile
field becomes visible to all readers (other threads in particular) after a write operation completes on it. Without volatile
, readers could see some non-updated value.
To answer your question: Yes, I use a volatile
variable to control whether some code continues a loop. The loop tests the volatile
value and continues if it is true
. The condition can be set to false
by calling a "stop" method. The loop sees false
and terminates when it tests the value after the stop method completes execution.
The book "Java Concurrency in Practice," which I highly recommend, gives a good explanation of volatile
. This book is written by the same person who wrote the IBM article that is referenced in the question (in fact, he cites his book at the bottom of that article). My use of volatile
is what his article calls the "pattern 1 status flag."
If you want to learn more about how volatile
works under the hood, read up on the Java memory model. If you want to go beyond that level, check out a good computer architecture book like Hennessy & Patterson and read about cache coherence and cache consistency.
Why do we use volatile keyword?
Consider this code,
int some_int = 100;
while(some_int == 100)
{
//your code
}
When this program gets compiled, the compiler may optimize this code, if it finds that the program never ever makes any attempt to change the value of some_int
, so it may be tempted to optimize the while
loop by changing it from while(some_int == 100)
to something which is equivalent to while(true)
so that the execution could be fast (since the condition in while
loop appears to be true
always). (if the compiler doesn't optimize it, then it has to fetch the value of some_int
and compare it with 100, in each iteration which obviously is a little bit slow.)
However, sometimes, optimization (of some parts of your program) may be undesirable, because it may be that someone else is changing the value of some_int
from outside the program which compiler is not aware of, since it can't see it; but it's how you've designed it. In that case, compiler's optimization would not produce the desired result!
So, to ensure the desired result, you need to somehow stop the compiler from optimizing the while
loop. That is where the volatile
keyword plays its role. All you need to do is this,
volatile int some_int = 100; //note the 'volatile' qualifier now!
In other words, I would explain this as follows:
volatile
tells the compiler that,
"Hey compiler, I'm volatile and, you
know, I can be changed by some XYZ
that you're not even aware of. That
XYZ could be anything. Maybe some
alien outside this planet called
program. Maybe some lightning, some
form of interrupt, volcanoes, etc can
mutate me. Maybe. You never know who
is going to change me! So O you
ignorant, stop playing an all-knowing
god, and don't dare touch the code
where I'm present. Okay?"
Well, that is how volatile
prevents the compiler from optimizing code. Now search the web to see some sample examples.
Quoting from the C++ Standard ($7.1.5.1/8)
[..] volatile is a hint to the
implementation to avoid aggressive
optimization involving the object
because the value of the object might
be changed by means undetectable by an
implementation.[...]
Related topic:
Does making a struct volatile make all its members volatile?
When exactly do you use the volatile keyword in Java?
You basically use it when you want to let a member variable be accessed by multiple threads but do not need compound atomicity (not sure if this is the right terminology).
class BadExample {
private volatile int counter;
public void hit(){
/* This operation is in fact two operations:
* 1) int tmp = this.counter;
* 2) this.counter = tmp + 1;
* and is thus broken (counter becomes fewer
* than the accurate amount).
*/
counter++;
}
}
the above is a bad example, because you need compound atomicity.
class BadExampleFixed {
private int counter;
public synchronized void hit(){
/*
* Only one thread performs action (1), (2) at a time
* "atomically", in the sense that other threads can not
* observe the intermediate state between (1) and (2).
* Therefore, the counter will be accurate.
*/
counter++;
}
}
Now to a valid example:
class GoodExample {
private static volatile int temperature;
//Called by some other thread than main
public static void todaysTemperature(int temp){
// This operation is a single operation, so you
// do not need compound atomicity
temperature = temp;
}
public static void main(String[] args) throws Exception{
while(true){
Thread.sleep(2000);
System.out.println("Today's temperature is "+temperature);
}
}
}
Now, why can't you just use private static int temperature
? In fact you can (in the sense that that your program won't blow up or something), but the change to temperature
by the other thread may or may not be "visible" to the main thread.
Basically this means that it is even possible that your app. keeps writing Today's temperature is 0
forever if you don't use volatile
(in practice, the value tends to become eventually visible. However, you should not risk not using volatile when necessary, since it can lead to nasty bugs (caused by in-completely constructed objects etc.).
If you put volatile
keyword on something that doesn't need volatile
, it won't affect your code's correctness (i.e. the behaviour will not change). In terms of performance, it will depend on the JVM implementation. In theory you might get a tiny performance degradation because the compiler can't do reordering optimisations, have to invalidate CPU cache etc., but then again the compiler could prove that your field cannot ever be accessed by multiple threads and remove the effect of volatile
keyword completely and compile it to identical instructions.
EDIT:
Response to this comment:
Ok, but why can't we make todaysTemperature synchronized and create a synchronized getter for temperature?
You can and it will behave correctly. Anything that you can with volatile
can be done with synchronized
, but not vice versa. There are two reasons you might prefer volatile
if you can:
- Less bug prone: This depends on the context, but in many cases using
volatile
is less prone to concurrency bugs, like blocking while holding the lock, deadlocks etc. - More performant: In most JVM implementations,
volatile
can have significantly higher throughput and better latency. However in most applications the difference is too small to matter.
Volatile keyword in microcontrollers
volatile
keyword says to compiler do not optimize the variable which is prefixed with, the variable may change during run time by unknown source(not known to compiler) may be by an external interrupt etc.
No. The volatile
keyword does not tell the compiler to disable or not optimize a variable; the volatile
keyword tells the compiler that the variable (or rather the memory that the variable represents) may be modified externally to the program.
This has the effect that the compiler is no longer able to do the necessary analysis to determine if various optimizations are safe (that is functionally equivalent), so the compiler does not perform those optimizations. This is a necessary side-effect, but not the primarily purpose for the existence of the keyword.
The usage of volatile
as a somewhat or slightly portable hack of acting like a pragma
to disable the compiler's optimization is a fairly common pattern. Outside of embedded programming, this may be its most commonly encountered usage for application programmers.
The compiler knows all the interrupts of that controller. So in that case how the
volatile
keyword helps?
The volatile
keyword means the memory contents can be modified outside of the program's control, either in another process, thread, or by external signals such as a hardware interrupt.
Compilers don't "know" about interrupts, there may be system header files distributed with a compiler that define symbolic names for an interrupt, but that does not mean the compiler understands them.
Is there any other advantage of
volatile
?
Not that I can think of, beside what's described here.
[Does]
volatile
appl[y] to reading from files?
Except when used as an form of inter-process communication (IPC) or as a semaphore, the contents of a file are normally controlled by a single process, so the usage of volatile
is not necessary.
Related Topics
How to Detect Keypress While Not Focused
In Unity, How to Pass Values from One Script to Another
Replace Only Some Groups with Regex
What Does the M Stand for in C# Decimal Literal Notation
How to Keep the Delimiters of Regex.Split
How to Set Z-Order of a Control Using Winforms
Selenium Error - the Http Request to the Remote Webdriver Timed Out After 60 Seconds
C# Rsa Public Key Output Not Correct
Passing Dynamic Object to C# Method Changes Return Type
Getting Full Url of Action in ASP.NET MVC
Redirecting Unauthorized Controller in ASP.NET MVC
Is There an Alternative to String.Replace That Is Case-Insensitive