亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

對睡眠的調用將重新加載緩存在java寄存器中的值?

對睡眠的調用將重新加載緩存在java寄存器中的值?

青春有我 2022-08-03 12:36:19
在 java 規范 17.3 中 睡眠和產量17.3 睡眠和產量Thread.sleep 會導致當前正在執行的線程在指定的持續時間內休眠(暫時停止執行),具體取決于系統計時器和調度程序的精度和準確性。線程不會失去任何監視器的所有權,并且恢復執行將取決于調度和執行線程的處理器的可用性。請務必注意,Thread.sleep 和 Thread.yield 都沒有任何同步語義。特別是,編譯器不必在調用 Thread.sleep 或 Thread.yield 之前將寄存器中緩存的寫操作刷新到共享內存中,編譯器也不必在調用 Thread.sleep 或 Thread.yield 后重新加載寄存器中緩存的值。例如,在下面(斷開的)代碼片段中,假定 this.done 是一個非易失性布爾字段:while (!this.done)    Thread.sleep(1000);編譯器可以自由地讀取 this.done 字段一次,并在循環的每次執行中重用緩存的值。這意味著循環永遠不會終止,即使另一個線程更改了 this.done 的值它描述了線程從不重新加載寄存器中緩存的變量,但是當我運行以下代碼時,它不起作用,循環終止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");    }}結果是:java規范17.3中的代碼有一些不同之處?為什么字段 keepRunning 在調用睡眠后重新加載?    C:\Users\LuoYY\Desktop>javac TestDemo.java    C:\Users\LuoYY\Desktop>java TestDemo    keepRunning is false now    loop terminates
查看完整描述

2 回答

?
牛魔王的故事

TA貢獻1830條經驗 獲得超3個贊

規范沒有說編譯器(或運行時)必須確保該字段永遠不會被重新加載或與其他線程同步。

“不必”,“自由”,“沒有任何語義”

它只說允許這樣的行為(因為它在性能優化中是有意義的)。

因此,當涉及多個線程時,您必須明確說明它應該如何工作:要么使其易失性,要么使其成為線程本地線程。


查看完整回答
反對 回復 2022-08-03
?
米琪卡哇伊

TA貢獻1998條經驗 獲得超6個贊

再讀一遍:

“編譯器可以自由讀取這個字段,只需完成一次”

是免費的,這意味著它可以只閱讀一次,或者每次都可以自行決定閱讀它。在您的情況下,它每次都會讀取,這是規范允許的合法行為。


查看完整回答
反對 回復 2022-08-03
  • 2 回答
  • 0 關注
  • 141 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號