Search code examples
javamultithreadingvolatile

When Java refresh Thread Cache to actual copy


I read few articles on volatile Thread cache and found either it is too much brief without examples, so it is very difficult for beginner to understand.

Please help me in understanding below program,

public class Test {
    int a = 0;
    public static void main(String[] args) {        
        final Test t = new Test();
        new Thread(new Runnable(){
            public void run() {
                try {
                    Thread.sleep(3000);
                } catch (Exception e) {}
                t.a = 10;
                System.out.println("now t.a == 10");
            }
        }).start();

        new Thread(new Runnable(){
            public void run() {
                while(t.a == 0) {}
                System.out.println("Loop done: " + t.a);
            }
        }).start();
    }

}

When I make a variable volatile and run my program then it stops after some time but when I remove volatile to a variable, then it goes on and my program is not stopping.

What I knew about volatile is "when variable is declared as volatile then thread will directly read/write to variable memory instead of read/write from local thread cache. if not declared volatile then one can see delay in updation of actual value."

Also, as per my understanding of refreshing the cached copy, I thought program will stop in some time but then why in above program it is continuing to run and not updating.

So when is Thread referring to its local cache starts referring to main copy or refresh its value with main copy value?

Please correct me if I am wrong in my understanding....

Please explain me with some small code snippet or link.


Solution

  • when variable is declared as volatile then thread will directly read/write to variable memory instead of read/write from local thread cache. if not declared volatile then one can see delay in updation of actual value.

    To begin with, the above statements are false. There are many more phenomena going on at the level of machine code which have nothing to do with any "thread-local variable caches". In fact, this concept is hardly applicable at all.

    To give you something specific to focus on, the JIT compiler will be allowed to transform your code

    while(t.a == 0) {}
    

    into

    if (t.a == 0) while (true) {}
    

    whenever t.a is not volatile. The Java Memory Model allows any variable accessed in a data race to be treated as if the accessing thread was the only thread in existence. Since obviously this thread is not modifying t.a, its value can be considered a loop invariant and the check doesn't have to be repeated... ever.