2 回答

TA貢獻1876條經(jīng)驗 獲得超6個贊
每個線程都為性能創(chuàng)建了不同的已緩存版本的did,您的計數(shù)器線程太忙于進行計數(shù)計算,以至于沒有機會重新加載did。
易失性確保任何讀/寫都在主內(nèi)存上完成,始終更新 cpu 緩存副本。
Thread.sleep 總是暫停當前線程,因此即使 0 你的計數(shù)器線程被中斷一段<1ms的時間,這也足以讓線程被告知已完成變量更改。

TA貢獻1811條經(jīng)驗 獲得超5個贊
我不是 Java 專家,我什至不會用 Java 編程,但讓我嘗試一下。
Java 語言規(guī)范第 17 章定義了內(nèi)存操作(例如共享變量的讀寫)的happens-before關(guān)系。僅當寫入操作發(fā)生在讀取操作之前時,才保證一個線程的寫入結(jié)果對另一線程的讀取可見。同步和易失性構(gòu)造以及Thread.start()和Thread.join()方法可以形成happens-before關(guān)系。
如果您瀏覽該線程,它會提到執(zhí)行共享變量的線程時的“發(fā)生在”邏輯。所以我的猜測是,當您調(diào)用 Thread.sleep(0) 時,主線程能夠正確設(shè)置 did 變量,確保它“首先發(fā)生”。但是,在多線程環(huán)境中,甚至不能保證這一點。但由于代碼片段非常小,因此在這種情況下仍然可以工作。
總而言之,我只是運行了您的程序,并對變量“done”進行了微小的更改,并且該程序按預期工作:
private?static?volatile?boolean?done;
謝謝。也許其他人可以給你更好的解釋:P
添加回答
舉報