Synchronized注意事項

Table of Contents

1.概述

1.1實現方式

1.2使用方式

2.對象內部結構

2.1對象內部結構

2.2  Mark Word 在 32 位 JVM 中存儲內容  

2.3 Mark Word 在 64 位 JVM 中存儲內容   [ 待考證 ]  

3.鎖升級過程

4. 什麼時候用自旋鎖什麼時候用系統鎖?

5. 爲什麼Synchronized不能加在String和Integer等基本包裝類型上


1.概述

1.1實現方式

synchronized 是 JVM 內置鎖,通過內部對象 Monitor(監視器鎖)實現,基於進入與退出 Monitor 對象實現方法與代碼塊同步,監視器鎖的實現依賴底層操作系統的 Mutex lock (互斥鎖)實現

 

1.2使用方式

1.同步實例方法,鎖是當前實例對象

2.同步類方法.鎖是當前類對象

3.同步代碼塊,鎖是括號裏面的對象

 

 

2.對象內部結構

2.1對象內部結構

2.2  Mark Word 在 32 位 JVM 中存儲內容  

 

2.3 Mark Word 在 64 位 JVM 中存儲內容   [ 待考證 ]  

 

3.鎖升級過程

無鎖->偏向鎖->輕量級鎖->重量級鎖    [ 整個過程不可逆!!!! ]

 

4. 什麼時候用自旋鎖什麼時候用系統鎖?

自旋鎖: 執行時間短 且 線程數少  .

系統鎖: 執行時間長 或者 線程多. 

 

5. 爲什麼Synchronized不能加在String和Integer等基本包裝類型上

 

同步塊不應該加在String或基本包裝類型上,如Byte、Short、Integer、Long、Float、Double、Boolean、Character。

String不能用作同步塊的參數是因爲String爲不可變對象,任何String對象的改變都將產生一個新的String對象,這也將導致前面加的鎖不會被釋放,或者因爲String對象改變,其他線程拿到鎖影響到上一個正在拿着鎖執行任務的程序.

Integer、Boolean、Double、Long不能作爲同步塊參數的原因是他們是基本包裝類型,包裝類型有特殊的邏輯,用一句話說就是Java的自動封箱和解箱操作會導致這些對象在經過運算後不再是原來的對象

用複雜的話說就是:當把基本變量賦值給包裝類型的變量(其實編譯過後的操作就是調用包裝類型的靜態方法valueOf)或者調用靜態valueOf方法時:

  • Boolean返回的是緩存的對象。
  • 整型(Byte,Short,Integer,Long)會檢查該數字是否在1個字節可表示的有符號整數範圍內(-128~127),是則返回緩存對象,否則返回新對象。
  • Character會緩存整型值爲0~127的字符,同樣會檢查字符是否落在緩存範圍中,是則返回,否則返回新對象。
  • Double和Float的valueOf方法始終返回新對象。

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章