Search code examples
javamultithreadingvolatile

Need help in volatile and non volatile concept in implemented java code?


I wrote following code to understand the volatile concept in java but the output seems to be confusing rather than clarifying the concept. Corrections, clarifications and feedback are welcomed and appreciated.

package threading;

public class UnSyncRead {
    //volatile static int value = 987;
    static int value = 987;
    public static void main(String[] args) {


        ThreadEx4 t = new ThreadEx4(value);
        t.start();
        for(int i=0;i<4;i++) {
            Thread thread = new Thread( new ThreadEx3(value));
            thread.start();
        }
    }

}

class ThreadEx3 implements Runnable{
private int i;
    public ThreadEx3(int i) {
        this.i=i;
}

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getId()+ "  "+Thread.currentThread().getName()+" "+ " inside "+i);
    }



}

class ThreadEx4 extends Thread{
    private int i;
    public ThreadEx4(int i) {
        this.i=i;
    }
    public void run() {
        ++i;
        System.out.println("changed the value to "+i);
    }
}

This program gives the following output

changed the value to 988
12  Thread-1  inside 987
13  Thread-2  inside 987
14  Thread-3  inside 987
15  Thread-4  inside 987

but if I modify the code to make value variable volatile by doing following change and running the code.

public class UnSyncRead {
volatile static int value = 987;
//static int value = 987;
public static void main(String[] args) {


    ThreadEx4 t = new ThreadEx4(value);
    t.start();
    for(int i=0;i<4;i++) {
        Thread thread = new Thread( new ThreadEx3(value));
        thread.start();
    }
}

}

I get following output which is exactly same when I ran it without volatile keyword.

changed the value to 988
12  Thread-1  inside 987 
13  Thread-2  inside 987
14  Thread-3  inside 987
15  Thread-4  inside 987 

My question is why the threads in the for loop are still reading the value of value variable as 987 and not 988, even after implementing volatile keyword.

Will deeply appreciate answer to this problem.


Solution

  • This has nothing to do with multithreading at all, it is a much more fundamental issue.

    class ThreadEx4 extends Thread{
        private int i;
        public ThreadEx4(int i) {
            this.i=i;
        }
        public void run() {
            ++i;
            System.out.println("changed the value to "+i);
        }
    }
    

    You are changing your private variable i here, not the global static field.

    Java passes things around by value. So when you say new ThreadEx4(myInteger), the constructor will receive the number inside of myInteger. Whatever it does to its local copy does not affect myInteger at all.

    To continue your multi-threading experiments, get rid of the local variables and do

    class Ex4 extends Runnable {
          @Override
          public void run(){
              int newValue = ++UnSyncRead.value;
              System.out.println("changed the value to "+newValue);
          }
    }
    // and the same for the other runnables