0

I'm trying to understand working of volatile variable. I have created a simple class "A" which extends "Thread" and has a volatile variable "i". There's another class "Amain" that runs 3 threads of class "A". I'm running a loop inside run() of A which depends on this volatile variable. Here the code.

// Thread

public class A extends Thread {

    public volatile int i = 0;

    @Override
    public void run() {

        while(i<10)
            System.out.println(i++ + "  " + this.getName());
    }
}

// Main Class

public class Amain {

    public static void main(String[] args) {

        A t1 = new A();
        A t2 = new A();
        A t3 = new A();

        t1.start();
        t2.start();
        t3.start();
    }

}

If the volatile value is shared among all threads then "i" should have been printed 10 times. Instead its printing 10 values for each thread i.e a total of 30 values. Need to understand working of volatile in context of this code. Also what can I do to get only 10 values of i from any number of threads(in context of this code).

TheLostMind
  • 35,966
  • 12
  • 68
  • 104
Punit
  • 69
  • 1
  • 7
  • @NitinDandriyal Got it. It works in the same manner if I make it "static" or "static volatile" i.e I get only 10 values. So what difference does volatile makes? – Punit May 19 '15 at 07:00
  • Read through this [volatile variables and other variables](http://stackoverflow.com/questions/12438464/volatile-variables-and-other-variables?rq=1) – Santhosh May 19 '15 at 07:03
  • Thanks everyone. I read some more post after your comments and answers. Got it now. – Punit May 21 '15 at 21:44

3 Answers3

7

In your case you created three separate A objects each of them having its separate i field, thus no shared state here. If you want a variable to be shared, declare it as static:

public static volatile int i = 0;

Note that even if variable is volatile, it's still unsafe to increment it. Use AtomicInteger instead.

Tagir Valeev
  • 97,161
  • 19
  • 222
  • 334
  • 1
    And if using an `AtomicInteger`, then _volatile_ is not needed anymore. The variable can then be final (it will not be updated anymore). – Seelenvirtuose May 19 '15 at 07:09
2

In your case, there is no shared state. i.e, the volatile field is not shared among threads. each thread has its own instance of i so your code is thread safe. If you declare i as static, then it will be shared, then you can see what volatileactually does.

TheLostMind
  • 35,966
  • 12
  • 68
  • 104
0

volatile keyword is used so that all the threads accessing that variable could see latest update for that variable.

In your case int i is a class member and in main() method 3 separate instances of class A is created so each thread will have their own independent copy of variable i. That is why you see 30 numbers in total. If you declare variable i as public static volatile int i = 0;, it will be shared among all the threads and you will not see 30 numbers in console.

Just to make sure that the increment operation is atomic, you also need to put i++ in a synchronized block or you can declare i as AtomicInteger instead of int.

Refer Simplest and understandable example of volatile keyword in java for more info.

Community
  • 1
  • 1
justAbit
  • 4,226
  • 2
  • 19
  • 34