Java單線程指令重排序:會(huì)改變輸出結(jié)果嗎?
java編譯器和處理器會(huì)為了性能優(yōu)化而對(duì)指令進(jìn)行重排序。這種重排序在多線程環(huán)境下可能引發(fā)問題,但單線程環(huán)境下通常不會(huì)影響程序的正確性。
讓我們來看一個(gè)例子:
System.out.println("1"); System.out.println("2");
這兩行簡(jiǎn)單的打印語句,在單線程下會(huì)因?yàn)橹噶钪嘏判蚨鴮?dǎo)致輸出變?yōu)?#8221;21″嗎?乍一看,由于沒有數(shù)據(jù)依賴性,似乎有可能。
答案是否定的。如果重排序能導(dǎo)致這種結(jié)果,那就不只是簡(jiǎn)單的重排序,而是徹底的亂序執(zhí)行了。 Java內(nèi)存模型雖然允許指令重排序,但它必須遵守一定的規(guī)則,以保證單線程程序的執(zhí)行結(jié)果不變。在這個(gè)例子中,即使沒有數(shù)據(jù)依賴,Java內(nèi)存模型也確保了單線程下的執(zhí)行順序不會(huì)被打亂。因此,輸出結(jié)果始終是”12″,而不是”21″。
立即學(xué)習(xí)“Java免費(fèi)學(xué)習(xí)筆記(深入)”;
需要注意的是,指令重排序主要在多線程環(huán)境下帶來影響。多線程環(huán)境下,線程間的可見性和順序性問題,可能會(huì)因?yàn)橹噶钪嘏判蚨鴮?dǎo)致不可預(yù)測(cè)的結(jié)果。然而,在單線程環(huán)境中,Java內(nèi)存模型保證了程序執(zhí)行結(jié)果的可預(yù)測(cè)性,指令重排序不會(huì)改變最終輸出。