Synconized,對象,鎖,鎖升級

  • 對於普通同步方法,鎖是當前實例對象

  • 對於靜態同步方法,鎖是當前class類對象

  • 對於同步方法塊,鎖是括號內對象。

JVM基於進入和退出Monitor對象來實現方法和代碼塊同步。每個java對象都有一個Monitor與之對應。代碼塊同步是用monitorenter和monitorexit關鍵字實現。monitor的本質是依賴於底層操作系統的Mutex Lock實現。

synchronized用的鎖是在Java對象頭裏的。如果對象是數組類型,則虛擬機用3個字寬存儲對象頭。如果對象是非數組類型,則用2個字寬存儲對象頭。在32位虛擬機中,1字寬=4字節(32bit)

對象頭信息

長度 內容 說明

32/64bit

Mark word

存儲對象的HashCode或鎖信息

同上

Class Metadata Adress

存儲到對象類型數據的指針

32bit

Array length

數組長度(如果對象是數組)

mark word在運行期間會隨着鎖標誌位變化而變化。(鎖升級)

鎖升級

 

JSE1.6做的優化

1.6中鎖一共有4種狀態:

  • 無鎖

  • 偏向鎖(自旋)

  • 輕量級鎖(自旋)

  • 重量級鎖

無鎖

無競爭就無鎖

偏向鎖(可重入鎖)

偏向鎖的markWord記錄的是持有鎖的線程id

出現競爭的時候用CAS來獲取鎖。出現競爭就做偏向鎖撤銷邏輯,如果做撤銷操作時,有線程持有偏向鎖,則偏向鎖升級爲輕量級鎖,將Mark word信息修改爲輕量級鎖,並copy到原偏向鎖線程中。

輕量級鎖

CAS操作將對象頭的Mark word中鎖記錄指針指向當前線程鎖記錄。說明哪個線程持有鎖。

CAS操作失敗達到一定次數之後(10?),升級爲重量鎖,等待喚醒。

重量級鎖

mark word指向Monitor對象的指針,互斥鎖,阻塞沒有競爭到鎖的線程

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