Search code examples
javavolatile

can the machine get visibility of other variables before read the volatile variable?


i know volatile can change the visibility ,so i can read b, but why if i put b=null before a = null,the run body won't end through break, it can see b=null before access the volatile variable a?

public class VolatileObjectTest4 implements Runnable {

    public volatile Object a;
    public Object b = new Object();
    public Object c;

    public VolatileObjectTest4(Object a) {
        this.a = a;
    }

    @Override
    public void run() {
        long i = 0;
        while (b != null) {
            //c = a;i=1;
            if (a == null) { //if i comment the next four lines, the loop won't break ,if i read the volatile `a`, the loop absolutely break;
                i = 1;
                break;
            }
            i++;
        }
        System.out.println("stop My Thread " + i);
    }

    public void stop() {
        System.out.println("stop");
        //b = null; // if comment this line, i = 1
        a = null;
        b = null;  //  if comment this line, i != 1

    }

    public static void main(String[] args) throws InterruptedException {

        VolatileObjectTest4 test = new VolatileObjectTest4(new Object());
        new Thread(test).start();

        Thread.sleep(1000);
        test.stop();
        Thread.sleep(1000);
        System.out.println("Main Thread " + test.getA() + test.c);
    }

}

Solution

  • Both your null assignments in stop() could occur anywhere during run(). Ordering them won't change how random the loop can break. You can breakpoint both methods and step through all combinations to prove it, it has little to do with volatile.

    Volatile may have created a memory barrier to force a 'happens before' situation (prevent compiler reordering instruction), but that still could cause what you observed.