What Is the Use of Volatile Keyword

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?

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.

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

Purpose/advantages of volatile

When a multithreaded program is running, and there is some shared variable which isn't declared as volatile, what these threads do is create a local copy of the variable, and work on the local copy instead. So the changes on the variable aren't reflected. This local copy is created because cached memory access is much faster compared to accessing variables from main memory.

When you declare a variable as volatile, it tells the program NOT to create any local copy of the variable and use the variable directly from the main memory.

By declaring a variable as volatile, we are telling the system that its value can change unexpectedly from anywhere, so always use the value which is kept in the main memory and always make changes to the value of the variable in the main memory and not create any local copies of the variable.

Note that volatile is not a substitute for synchronization, and when a field is declared volatile, the compiler and runtime are put on notice that this variable is shared and that operations on it should not be reordered with other memory operations. Volatile variables are not cached in registers or in caches where they are hidden from other processors, so a read of a volatile variable always returns the most recent write by any thread.

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:

  1. 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.
  2. 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.

What is the purpose of 'volatile' keyword in C#

I refer you to section 10.5.3 of the specification, which states:

For non-volatile fields, optimization
techniques that reorder instructions
can lead to unexpected and
unpredictable results in
multi-threaded programs that access
fields without synchronization such as
that provided by the lock-statement
(§8.12). These optimizations can be
performed by the compiler, by the
run-time 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.

These restrictions ensure
that all threads will observe volatile
writes performed by any other thread
in the order in which they were
performed. A conforming implementation
is not required to provide a single
total ordering of volatile writes as
seen from all threads of execution.

Read that extremely carefully if you have any intention of ever making a volatile field. If you do not completely and thoroughly understand all the implications of volatile semantics then do not attempt to use them. It is usually far better to use a lock, which automatically gives you sufficient memory barriers to ensure the necessary acquire and release semantics. Remember, locks are only really expensive when they are contended.



Related Topics



Leave a reply



Submit