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

為了賬號安全,請及時綁定郵箱和手機立即綁定

synchronized是否限制內部代碼的重排序

synchronized所修飾的內部代碼是否會重排序

正在回答

3 回答

補充一個問題
之前工作的時候寫單例模式,舉例如下,主管非得讓加volatile來修飾single,說如果不加會有重排序問題,從而導致空指針,但是看到大家的討論和老師的回答,我覺得不需要加volatile,因為synchronized關鍵字已經保證了只會有一個線程進入創建單例對象的代碼,當這個線程鎖釋放的時候,因為happens-before原則,其他線程拿到的單例一定是完整的,也就是說這個單例的屬性一定是已經被賦值的,不會出現空指針問題,請問老師我的理解準確嗎

public?class?ExampleSingle?{

????private?volatile?static?ExampleSingle?single;
????????***一些屬性
????private?ExampleSingle()?{
????????????***?假如這里對這些屬性進行了賦值操作
????}

????public?static?ExampleSingle?getInstance()?{
????????if?(single?==?null)?{
????????????synchronized?(ExampleSingle.class)?{
????????????????if?(single?==?null)?{
????????????????????single?=?new?ExampleSingle();
????????????????}
????????????}
????????}
????????return?single;
????}
}


0 回復 有任何疑惑可以回復我~
#1

是淚還是累

single = new ExampleSingle(); 大體分為三步 1.分配內存 2.初始化 3.將引用指向內存地址 你這個方法 ExampleSingle并沒有加sychronized,所以是不阻塞,可以進來,可sychronized并不保證指令重排序,所以3.將引用指向內存地址 重排序到2.初始化前,那么就這時single != null 而直接返回,退出方法,人家還沒有執行第二步初始化,所以拿到了一個未初始化后的single,進行操作就會出現問題,所以需要引入volatile進行禁止重排序,禁止了2和3的操作重排序。
2022-08-09 回復 有任何疑惑可以回復我~

不會限制,被synchronized修飾的代碼會被編譯器或者處理器重排序。多個線程如果不加同步鎖,重排序可能會導致可見性問題(線程A中代碼順序不一致可能導致線程B得到錯誤的結果,即使線程A符合as-if-serial語義),而如果加了同步鎖,不會導致可見性問題,因為線程A的所有操作對于線程B來說都是可見的。synchronized的作用主要是兩點:1.保證有序性:使多個線程之間有序執行,不會出現交叉執行。2.保證可見性:線程解鎖前,必須把共享變量的最新值刷新到主內存中,線程加鎖時,需要從主內存中重新讀取最新值。


0 回復 有任何疑惑可以回復我~

不會,它的作用是在多線程情況下的。單線程下重排序是不會影響執行結果的。

0 回復 有任何疑惑可以回復我~

舉報

0/150
提交
取消

synchronized是否限制內部代碼的重排序

我要回答 關注問題
微信客服

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

幫助反饋 APP下載

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

公眾號

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