Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Volatile in java

As far as I know volatile write happens-before volatile read, so we always will see the freshest data in volatile variable. My question basically concerns the term happens-before and where does it take place? I wrote a piece of code to clarify my question.

class Test {
   volatile int a;
   public static void main(String ... args) {
     final Test t = new Test();
     new Thread(new Runnable(){
        @Override
        public void run() {
            Thread.sleep(3000);
            t.a = 10;
        }
     }).start();
     new Thread(new Runnable(){
        @Override
        public void run() {
            System.out.println("Value " + t.a);
        }
     }).start();
   }
}

(try catch block is omitted for clarity)

In this case I always see the value 0 to be printed on console. Without Thread.sleep(3000); i always see value 10. Is this a case of happens-before relationship or it prints 'value 10' because thread 1 starts a bit earlier thread 2?

It would be great to see the example where the behaviour of code with and without volatile variable differs in every program start, because the result of code above depends only(at least in my case) on the order of threads and on thread sleeping.

like image 341
maks Avatar asked Jun 04 '12 21:06

maks


People also ask

When should we use volatile in Java?

The volatile modifier is used to let the JVM know that a thread accessing the variable must always merge its own private copy of the variable with the master copy in the memory. Accessing a volatile variable synchronizes all the cached copied of the variables in the main memory.

What is transient and volatile in Java?

Volatile and Transient are two completely different keywords that are used in Java. A Transient keyword is used during serialization of Java object. Volatile is related to the visibility of variables modified by multiple threads.

Why is volatile keyword used?

The volatile keyword is intended to prevent the compiler from applying any optimizations on objects that can change in ways that cannot be determined by the compiler. Objects declared as volatile are omitted from optimization because their values can be changed by code outside the scope of current code at any time.

What is difference between volatile and static?

This should read static variables are shared among objects all objects regardless of threads. "volatile variables are shared among multiple threads(so objects as well)." Volatile does not change how variables are shared among multiple threads or objects. It changes how the runtime is allowed to cache the value.


1 Answers

You see the value 0 because the read is executed before the write. And you see the value 10 because the write is executed before the read.

If you want to have a test with more unpredictable output, you should have both of your threads await a CountDownLatch, to make them start concurrently:

final CountDownLatch latch = new CountDownLatch(1);
new Thread(new Runnable(){
    @Override
    public void run() {
        try {
            latch.await();
            t.a = 10;
        }
        catch (InterruptedException e) {
            // end the thread
        }
    }
 }).start();
 new Thread(new Runnable(){
    @Override
    public void run() {
        try {
            latch.await();
            System.out.println("Value " + t.a);
        }
        catch (InterruptedException e) {
            // end the thread
        }
    }
 }).start();
 Thread.sleep(321); // go
 latch.countDown();
like image 193
JB Nizet Avatar answered Sep 21 '22 12:09

JB Nizet