0

I am trying to understand java volatile and my understanding is that in the attached code there is a possibility of Reader thread not seeing the Writer threads updates made to the sharedData because the counter variable isn't declared volatile. However in multiple runs I have seen that the changes of WriterThread are immediately visible to the ReaderThread even though I am not using volatile with the counter variable. Can some one point out where I am going wrong please?

public class App 
{
    public static void main( String[] args )
    {
        SharedData sharedData = new SharedData();

        new WriterThread(sharedData, "Writer1").start();;

        new ReaderThread(sharedData, "Reader1").start();;
    }
}


class SharedData{
    public int counter=0;
}


class ReaderThread extends Thread{

    private SharedData sharedData;
    ReaderThread(SharedData sd , String name){
        super(name);
        this.sharedData = sd;
    }
    public void run() {
        while(true) {
        System.out.println(this.getName() + ": " + sharedData.counter);
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        }
    }

}

class WriterThread extends Thread{

    private SharedData sharedData;
    WriterThread(SharedData sd , String name){
        super(name);
        this.sharedData = sd;
    }
    public void run() {
        while(true) {
        System.out.println(this.getName() + ": " + ++sharedData.counter);
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        }

    }

} 
Cœur
  • 37,241
  • 25
  • 195
  • 267
Javadee
  • 139
  • 10
  • 5
    Java doesn't say that the value **won't** be visible without `volatile`. It says that the value **may not** be visible. IOW without `volatile` the result is non-deterministic. – markspace May 02 '18 at 19:23
  • As you wrote yourself, *there is a possibility*. You simply didn't run into a situation where this would happen. Anecdotally, we had a piece of code in our codebase that ran in parallel and a test for it, and the test failed every once in a couple months (running daily). – Jiri Tousek May 02 '18 at 19:26
  • 1
    I'm a little surprise that your code above isn't optimized into a register and never visible, but thems the breaks. It's hard to predict exactly what the JIT optimizer will do, and usually not worth your time. Just write code correctly and don't worry about the edge cases like this where it "seems" to work. – markspace May 02 '18 at 19:27
  • Admin - The question isn't duplicate. The answer that you have pointed out is a situation where lack of volatile is causing the issue. Where as my question is why is my code working even without using volatile. Thanks, – Javadee May 02 '18 at 19:35
  • As @JiriTousek wrote: you gave the answer already. It is a probabilistic thing. Run your test often enough, and eventually it will fail. Add `volatile` and it will never fail. – Turing85 May 02 '18 at 19:39

0 Answers0