机器能否在读取 volatile 变量之前获得其他变量的可见性?
can the machine get visibility of other variables before read the volatile variable?
我知道 volatile 可以改变可见性,所以我可以读 b,但是为什么如果我把 b=null
放在 a = null
之前,运行 主体不会通过 break 结束,它可以在访问 volatile 变量 a
?
之前看到 b=null
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() 中的两个空赋值都可能在 运行() 期间的任何地方发生。对它们进行排序不会改变循环中断的随机程度。两种方法都可以断点,遍历所有组合来证明,跟volatile关系不大。
易失性 可能 已经创建了一个内存屏障来强制 'happens before' 情况(防止编译器重新排序指令),但这仍然可能导致您观察到的情况。
我知道 volatile 可以改变可见性,所以我可以读 b,但是为什么如果我把 b=null
放在 a = null
之前,运行 主体不会通过 break 结束,它可以在访问 volatile 变量 a
?
b=null
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() 中的两个空赋值都可能在 运行() 期间的任何地方发生。对它们进行排序不会改变循环中断的随机程度。两种方法都可以断点,遍历所有组合来证明,跟volatile关系不大。
易失性 可能 已经创建了一个内存屏障来强制 'happens before' 情况(防止编译器重新排序指令),但这仍然可能导致您观察到的情况。