在 java 規(guī)范 17.3 中 睡眠和產(chǎn)量17.3 睡眠和產(chǎn)量Thread.sleep 會(huì)導(dǎo)致當(dāng)前正在執(zhí)行的線程在指定的持續(xù)時(shí)間內(nèi)休眠(暫時(shí)停止執(zhí)行),具體取決于系統(tǒng)計(jì)時(shí)器和調(diào)度程序的精度和準(zhǔn)確性。線程不會(huì)失去任何監(jiān)視器的所有權(quán),并且恢復(fù)執(zhí)行將取決于調(diào)度和執(zhí)行線程的處理器的可用性。請(qǐng)務(wù)必注意,Thread.sleep 和 Thread.yield 都沒有任何同步語義。特別是,編譯器不必在調(diào)用 Thread.sleep 或 Thread.yield 之前將寄存器中緩存的寫操作刷新到共享內(nèi)存中,編譯器也不必在調(diào)用 Thread.sleep 或 Thread.yield 后重新加載寄存器中緩存的值。例如,在下面(斷開的)代碼片段中,假定 this.done 是一個(gè)非易失性布爾字段:while (!this.done) Thread.sleep(1000);編譯器可以自由地讀取 this.done 字段一次,并在循環(huán)的每次執(zhí)行中重用緩存的值。這意味著循環(huán)永遠(yuǎn)不會(huì)終止,即使另一個(gè)線程更改了 this.done 的值它描述了線程從不重新加載寄存器中緩存的變量,但是當(dāng)我運(yùn)行以下代碼時(shí),它不起作用,循環(huán)終止public class TestDemo { private static boolean keepRunning = true; public static void main(String[] args) throws Exception { new Thread( ()->{ while (keepRunning){ try { Thread.sleep(1000); } catch (InterruptedException e) { } } System.out.println("loop terminates"); } ).start(); Thread.sleep(1000); keepRunning = false; System.out.println("keepRunning is false now"); }}結(jié)果是:java規(guī)范17.3中的代碼有一些不同之處?為什么字段 keepRunning 在調(diào)用睡眠后重新加載? C:\Users\LuoYY\Desktop>javac TestDemo.java C:\Users\LuoYY\Desktop>java TestDemo keepRunning is false now loop terminates
2 回答

牛魔王的故事
TA貢獻(xiàn)1830條經(jīng)驗(yàn) 獲得超3個(gè)贊
規(guī)范沒有說編譯器(或運(yùn)行時(shí))必須確保該字段永遠(yuǎn)不會(huì)被重新加載或與其他線程同步。
“不必”,“自由”,“沒有任何語義”
它只說允許這樣的行為(因?yàn)樗谛阅軆?yōu)化中是有意義的)。
因此,當(dāng)涉及多個(gè)線程時(shí),您必須明確說明它應(yīng)該如何工作:要么使其易失性,要么使其成為線程本地線程。

米琪卡哇伊
TA貢獻(xiàn)1998條經(jīng)驗(yàn) 獲得超6個(gè)贊
再讀一遍:
“編譯器可以自由讀取這個(gè)字段,只需完成一次”
是免費(fèi)的,這意味著它可以只閱讀一次,或者每次都可以自行決定閱讀它。在您的情況下,它每次都會(huì)讀取,這是規(guī)范允許的合法行為。
添加回答
舉報(bào)
0/150
提交
取消