課程
/后端開發
/Java
/細說Java多線程之內存可見性
synchronized所修飾的內部代碼是否會重排序
2019-04-08
源自:細說Java多線程之內存可見性 4-1
正在回答
補充一個問題之前工作的時候寫單例模式,舉例如下,主管非得讓加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; ????} }
是淚還是累
不會限制,被synchronized修飾的代碼會被編譯器或者處理器重排序。多個線程如果不加同步鎖,重排序可能會導致可見性問題(線程A中代碼順序不一致可能導致線程B得到錯誤的結果,即使線程A符合as-if-serial語義),而如果加了同步鎖,不會導致可見性問題,因為線程A的所有操作對于線程B來說都是可見的。synchronized的作用主要是兩點:1.保證有序性:使多個線程之間有序執行,不會出現交叉執行。2.保證可見性:線程解鎖前,必須把共享變量的最新值刷新到主內存中,線程加鎖時,需要從主內存中重新讀取最新值。
不會,它的作用是在多線程情況下的。單線程下重排序是不會影響執行結果的。
舉報
用兩種方式實現內存可見性,代領大家深層次學習Java中的內存
2 回答關于重排序
2 回答重排序問題
1 回答重排序由誰來做?
3 回答java有編譯器或者運行環境會重新排序代碼指令,.NET有嗎?
1 回答synchronized(this) 中this代表是什么呀?
Copyright ? 2025 imooc.com All Rights Reserved | 京ICP備12003892號-11 京公網安備11010802030151號
購課補貼聯系客服咨詢優惠詳情
慕課網APP您的移動學習伙伴
掃描二維碼關注慕課網微信公眾號
2020-09-08
補充一個問題
之前工作的時候寫單例模式,舉例如下,主管非得讓加volatile來修飾single,說如果不加會有重排序問題,從而導致空指針,但是看到大家的討論和老師的回答,我覺得不需要加volatile,因為synchronized關鍵字已經保證了只會有一個線程進入創建單例對象的代碼,當這個線程鎖釋放的時候,因為happens-before原則,其他線程拿到的單例一定是完整的,也就是說這個單例的屬性一定是已經被賦值的,不會出現空指針問題,請問老師我的理解準確嗎
2020-05-25
不會限制,被synchronized修飾的代碼會被編譯器或者處理器重排序。多個線程如果不加同步鎖,重排序可能會導致可見性問題(線程A中代碼順序不一致可能導致線程B得到錯誤的結果,即使線程A符合as-if-serial語義),而如果加了同步鎖,不會導致可見性問題,因為線程A的所有操作對于線程B來說都是可見的。synchronized的作用主要是兩點:1.保證有序性:使多個線程之間有序執行,不會出現交叉執行。2.保證可見性:線程解鎖前,必須把共享變量的最新值刷新到主內存中,線程加鎖時,需要從主內存中重新讀取最新值。
2020-05-07
不會,它的作用是在多線程情況下的。單線程下重排序是不會影響執行結果的。