Wednesday, August 20, 2014

Java volatile keyword by example

    Volatile keyword seems to be a little bit enigmatic at first glance. It is rather rare to see that keyword on a daily basis. How does it work? What effect can it have on the program execution?
The following experiments were performed on jdk1.8.0_05 and Core i5 (Sandy Bridge) processor under Window 7 system. I have prepared a really simple example:
public class ChangeMe {

 private static long changeMe = 0xDeadBeef;

 public static void main(String[] args) {

  Thread t = new Thread(new Runnable() {
   @Override
   public void run() {
    while (true)
     changeMe = System.currentTimeMillis();
   }
  });
  t.setDaemon(true);
  t.start();

  while (changeMe == changeMe)
   System.out.println(System.currentTimeMillis());
  
 }
}
When you execute that piece of code there is a great chance the program flow will last forever. Well, it can be finished after a couple of seconds but when JVM is warmed up - the program execution will not be stopped. You just need to try a couple of times if you are not lucky.
Now, we can modify that code just a little bit:
public class ChangeMe {

 private static volatile long changeMe = 0xDeadBeef;

 public static void main(String[] args) {

  Thread t = new Thread(new Runnable() {
   @Override
   public void run() {
    while (true)
     changeMe = System.currentTimeMillis();
   }
  });
  t.setDaemon(true);
  t.start();

  while (changeMe == changeMe)
   System.out.println(System.currentTimeMillis());
  
 }
}
The execution is stopped after a few seconds. Thanks to volatile keyword - the memory synchronization is enforced - every thread accessing a volatile field must refresh its own copy of that variable. Otherwise, the thread usually just sees its local copy of a shared variable. There is also one more way to enforce memory synchronization:
public class ChangeMe {

 private static long changeMe = 0xDeadBeef;

 public static void main(String[] args) {

  Thread t = new Thread(new Runnable() {
   @Override
   public void run() {
    while (true)
     changeMe = System.currentTimeMillis();
   }
  });
  t.setDaemon(true);
  t.start();

  while (getChangeMe() == getChangeMe())
   System.out.println(System.currentTimeMillis());
  
 }
 
 private static synchronized long getChangeMe() {
  return changeMe;
 }
}
Synchronized keyword does the same thing as volatile keyword - memory synchronization - but it also enforces exclusivity - it is much stronger keyword than volatile.
I believe this hands-on experience shed some light on the mysterious Java keyword.

2 comments :

  1. "every thread accessing a volatile field must refresh its own copy of that variable" - i have recently came across statement, that when, for example, thread X is accessing volatile variable previously written to by thread Y, all variables visible to thread Y prior to writing to volatile var are now visible for thread X. It does not make much sense for me.

    ReplyDelete
  2. Its Pleasure to read your blog.The above articles is very impressive, and I really enjoyed reading your blog and points that you expressed. I love to come back on a regular basis,post more on the subject.

    evs full form
    raw agent full form
    full form of tbh in instagram
    dbs bank full form
    https full form
    tft full form
    pco full form
    kra full form in hr
    tbh full form in instagram story
    epc full form

    ReplyDelete