Friday, June 3, 2011

How Volatile in Java works ? Example of volatile keyword in Java

How to use Volatile keyword in Java

Volatile keyword in Java is used as an indicator to Thread that do not cache value of this variable and always read it from main memory. So if you want to share any variable in which operations read and write is atomic by implementation e.g. read and write in int or boolean variable you can make it volatile. with Java5 and change in Java Memory Model , Java guarantees visibility of changes made by one thread to another also as "happens-before" which solves the problem of Memory writes that happen in one thread can "leak through" and be seen by another thread. Java volatile keyword cannot be used with method or class and it can only be used with variable. Java volatile keyword also guarantees visibility and ordering , after java5 write to any volatile variable happens before any read into volatile variable. also use of volatile keyword prevents compiler or JVM from reordering of code.

java volatile keyword example and tutorial 
This Java volatile  tutorial is in continuation of my article How HashMap works in Java  and difference between HashMap and Hashtable in Java  , How Garbage collection works in Java and How Synchronization works in Java if you haven’t read already you may find some useful information based on my experience in Java .


Example of volatile keyword in Java:

To Understand example of volatile keyword in java let’s go back to Singleton pattern in Java and see double checked locking in Singleton with Volatile and without volatile keyword in java.

public class Singleton{
private static volatile Singleton _instance;

public static Singleton getInstance(){

   if(_instance == null){
            synchronized(Singleton.class){
              if(_instance == null)
              _instance = new Singleton();
            }

   }
   return _instance;

}

If you look at the code carefully you will be able to figure out:
1) We are only creating instance one time
2) We are creating instance lazily at the time of first request comes.

If we do not make _instance variable volatile then Thread which is creating instance of Singleton is not able to communicate other thread, that instance has been created until it comes out of the Singleton block, so if Thread A is creating Singleton instance and just after creation lost the CPU, all other thread will not be able to see value of _instance as not null and they will believe its still null.


Why because reader threads are not doing any locking and until writer thread comes out of synchronized block, memory will not be synchronized and value of _instance will not be updated in main memory. With Volatile keyword in Java this is handled by Java himself and such updates will be visible by all reader threads.

So in Summary apart from synchronized keyword in java, volatile keyword is also used to communicate content of memory between threads.

Let’s see another example of volatile keyword in Java:

most of the time while writing game we use a variable bExist to check whether user has pressed exit button or not, value of this variable is updated in event thread and checked in game thread , So if we don't  use volatile keyword with this variable , Game Thread might miss update from event handler thread if its not synchronized in java already. volatile keyword in java guarantees that value of volatile variable will always be read from main memory  and  "happens-before" relationship in Java Memory model will ensure that content of memory will be communicated to different threads.


 boolean bExit;

 while(!bExit) {
    checkUserPosition();
    updateUserPosition();
 }

In this code example One Thread (Game Thread) can cache the value of "bExit" instead of getting it from main memory every time and if in between any other thread (Event handler Thread) changes the value; it would not be visible to this thread. Making boolean variable "bExit" as volatile in java ensures this will not happen.



Important points on Volatile keyword in Java

1. Volatile keyword in Java is only application to variable and using volatile keyword with class and method is illegal.

2. Volatile keyword in Java guarantees that value of volatile variable will always be read from main memory and not from Thread's local cache.

3. In Java reads and writes are atomic for all variables declared using java volatile keyword (including long and double variables).

4. Using Volatile keyword in Java on variables reduces the risk of memory consistency errors, because any write to a volatile variable in Java establishes a happens-before relationship with subsequent reads of that same variable.

5. From Java 5 changes to a volatile variable are always visible to other threads. What’s more it also means that when a thread reads a volatile variable in java, it sees not just the latest change to the volatile variable but also the side effects of the code that led up the change.

6. Reads and writes are atomic for reference variables are for most primitive variables (all types except long and double) even without use of volatile keyword in Java.

7. An access to a volatile variable in Java never has chance to block, since we are only doing a simple read or write, so unlike a synchronized block we will never hold on to any lock or wait for any lock.
8. A java volatile variable that is an object reference may be null.

9. Java volatile keyword doesn't means atomic, its common misconception that after declaring volatile ++ will be atomic, to make the operation atomic you still need to ensure exclusive access using synchronized method or block in Java.

10. If a variable is not shared between multiple threads no need to use volatile keyword with that variable.


Difference between synchronized and volatile keyword in Java

1. Volatile keyword in java is a field modifier, while synchronized modifies code blocks and methods.

2. Synchronized obtains and releases lock on monitor’s java volatile keyword doesn't require that.

3. Threads in Java can be blocked for waiting any monitor in case of synchronized, that is not the case with volatile keyword in Java.

4. Synchronized method affects performance more than volatile keyword in Java.

5. Since volatile keyword in Java only synchronizes the value of one variable between Thread memory  and "main" memory  while synchronized synchronizes the value of all variable between thread memory and "main" memory and locks and releases a monitor to boot. Due to this reason synchronized keyword in Java is likely to have more overhead than volatile.

6. You can not synchronize on null object but your volatile variable in java could be null.

7. From Java 5 Writing into a volatile field has the same memory effect as a monitor release, and reading from a volatile field has the same memory effect as a monitor acquire

In Summary volatile keyword in Java is not a replacement of synchronized block or method but in some situation is very handy and can save performance overhead which comes with use of synchronization in java

if you like to know more about volatile I would recommend reading Jeremy's blogpost about volatility  , he has been involved in JSR 133 Java Memory model and explains complex concurrency concepts in simple language. I would also suggest to go thorough FAQ on Java Memory Model here which explains happens-before operations quite well.

Java tutorials you may like

Do you like Books?
If you love to read books here are few Java titles which is worth of money :
Please vote +1 or consider sharing if your like this article

16 comments:

Anand said...

This one is a Gem Javin!!!

Keep up the good work.

Anand.

Anonymous said...

hi, what is difference between volatile and synchronized keyword in java ? Can we use volatile in place of synchronized ? what will happen if we don't make variable volatile in Java ?

Javin @ String vs StringBuffer said...

Hi Anonymous, Volatile and Synchronized are completely different with each other. you can not use volatile keyword with methods while synchronized keyword can be used. similarly synchronized keyword can not be applied to variable while you can make variable volatile. to read more about synchronized read my post How Synchronization works in Java

Anonymous said...

Great post..Thanks

Barchist said...

Why not we can use volatile keyword with method ? why only variable needs to be volatile ? yes it may look some insane questions but I just want to know basics of volatile keyword ?

Anonymous said...

"atomic for reference variables are for most"
should be
"atomic for reference variables AND for most "

Anonymous said...

"Jeremy's blogpost about volatility , he" contains unnecessary spaces before the coma.

Anonymous said...

Volatile in Java is more of a documentation keyword, I never seen much usage of volatile keyword in most of project, what I have seen is synchronized and synchronized.

Aban said...

Hi,

For understanding and testing purpose I write a small pice of code as following:

VolatileTest.java
-------------------

public class VolatileTest extends Thread {

private volatile int testValue;
private volatile boolean ready;

public VolatileTest(String str) {
super(str);
}

public void run() {
for (int i = 0; i < 3; i++) {
try {
if (getName().equals("T1")) {
ready = true;
testValue = i;
System.out.println(getName() + " :: " + ready + " :: " + testValue);
}
if (getName().equals("T2")) {
System.out.println(getName() + " :: " + ready + " :: " + testValue);
}
Thread.sleep(1000);
} catch (InterruptedException exception) {
exception.printStackTrace();
}
}
}
}

TestVol .java
--------------
public class TestVol {
public static void main(String[] args) {
new VolatileTest("T1").start();
new VolatileTest("T2").start();
}
}

I am getting following output:
T1 :: true :: 0
T2 :: false :: 0
T1 :: true :: 1
T2 :: false :: 0
T1 :: true :: 2
T2 :: false :: 0

Can you please help me to understand, why this result is comming. As per my understanding, I should get "T2 :: true :: 0" (second line).

Regards,
Aban

Javin @ spring interview questions answers said...

Hi Aban, line 2 is correct since you are using two separate object of VolatileTest default value for boolean ready is false which is displaying. try using one object and share it between two threads.

Issamu said...

So to me it only makes sense using VOLATILE with a static field, is this assumption right?
As in Aban example, there is no need for testValue and ready being volatile because each instance of thread would have its own version of these fields, it's not shared between them.

Chris said...

you double-check-lock in the singleton, but it states on the java sun documentation (which you've linked to) that this doesnt work...

http://java.sun.com/developer/technicalArticles/Programming/singletons/

http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html

love the blog though

Javin @ spring interview questions answers said...

Hi Chris, Thanks for your comment. double check lock example will not work prior to Java5 but with change in Java memory model and guarantee provided by volatile keyword in Java , double checked locking will work if we make Singleton instance volatile. as I have mentioned in point 5 "From Java 5 changes to a volatile variable are always visible to other threads"

Peter Lawrey said...

This covers the issues well.

I would comment that the simplest singleton pattern is

enum Singleton { INSTANCE; }

its thread safe and lazy loading.

Unknown said...

Very Nice Article Javin....thnx for sharing the Java5 Thread Model...its really helpful..

Javin @ race condition in java said...

@Unknown,Thanks for comment. Glad to know that you like this Java volatile example and tutorial. you may like my other post on threading as well e.g. Why wait and notify are defined in Object class

Post a Comment

What is this blog about

This blog is about my experience in Java, Tibco Rendezvous and FIX protocol. FIX is a technology which is used to build equity trading system and heavily used in electronic trading , high frequency trading and Algorithmic trading, so on most of Investment bank job you need to know FIX Protocol on the other hand Tibco Rendezvous is used to implement messaging backbone on many big commercial and global banks. This blog help you to get clear any FIX protocol job interview. It also includes Java and Tibco Rendezvous article written for new user mainly my experience in my own word.