我們先看下面一個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變量還是從放在主存。所以就出現上面這種並發編程的變量可見行問題了。