synchonized是java中廣泛意義的鎖,通常都會稱之爲重量鎖。自從JDK1.6開始對synchonized進行優化,synchonized在某些狀況下也會轉變爲偏向鎖、輕量鎖、重量鎖,能夠認爲synchonized關鍵字是幾種鎖的封裝。java
- 用法:
- 原理:
使用javap反編譯擁有synchonized代碼塊的方法,發現synchonized代碼塊開始和結束(有異常)的地方分別有monitorenter和monitorexit指令,以下圖所示:

當執行到monitorenter時,獲取monitor(即代碼中的lockObj)的全部權,執行到monitorexit,釋放monitor的全部權,synchonized方法原理也相似。
- 底層實現:
synchonized將鎖的信息存在了Java對象頭的MarkWord裏,32位和64位操做系統Java對象頭的結構以下圖所示:

前面提到synchonized關鍵字包含有幾種狀態,從無鎖狀態->偏向鎖->輕量鎖->重量鎖 依次變化,鎖只能升級,不能降級,32位虛擬機MarkWord中存儲的鎖狀態信息以下:

推薦使用openjdk的JOL包來觀察MarkWord,一個無鎖狀態的截圖以下(圖中01爲鎖標識位):

幾種鎖的狀態升級過程比較複雜,另開一貼具體說明。
- 坑:
- 使用synchronized修飾代碼塊時,lock對象須要是全局的對象,若是lockObj在代碼塊所在方法內進行初始化,那麼鎖定無效,由於使用的鎖信息存儲在了不一樣的對象中。
- 使用JOL觀察MarkWord時,低位優先打印,所以上面無鎖狀態的截圖中01纔是鎖標誌位。
參考書籍及網址:編程
- 《Java併發編程的藝術》
- 《深刻理解Java虛擬機》
PS:研究基於MAC+Idea+JDK1.8 64位併發
Keep Calm and Carry on!優化