我们先看下面一个Java并发编程下变量可见行示例
public class RaceCondition {
private static boolean done;
public static void main(final String[] args) throws InterruptedException {
new Thread(new Runnable() {
public void run() {
int i = 0;
while (!done) {
i++;
}
System.out.println("Done!");
}
}).start();
System.out.println("OS: " + System.getProperty("os.name"));
Thread.sleep(2000);
done = true;
System.out.println("flag done set to true");
}
在Ubutun双核cpu下,默认不加任何jvm参数执行
输出如下: 主线程执行完之后,子线程一直在执行,为什么子线程没有获取到主线程修改done之后的变量值呢?
我们再设置下jvm的参数为 -client,则子线程能够获取主线程修改done之后的值,正常执行完
也就是moren ubutun下默认jvm启动是-server 服务器默认启动的,那么-server启动跟client启动有什么区别呢?-server启动多了JIT即时编译优化,JIT优化会对while循环进行优化,所以它没法看到主线程对done变量修改的值,子线程读取done变量会从操作系统寄存器或者cpu cache中读取done的值,而不会从主存中读取,而主线程修改done变量还是从放在主存。所以就出现上面这种并发编程的变量可见行问题了。