我知道volatile可以更改可见性,所以我可以读b,但是为什么如果我将b=null
放在a = null
之前,运行主体将不会中断,它可以在访问volatile变量之前看到b=null
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);
}
}
您在stop()中的空分配都可能在run()期间的任何地方发生。对它们进行排序不会改变循环的随机程度。您可以断点这两种方法,并逐步进行所有组合来证明这一点,这与volatile无关。
[Volatile may已经创建了一个内存屏障,以强制发生“先发生”(防止编译器重新排序的指令),但这仍然可能导致您观察到的结果。