synchorized鎖升級過程:
synchorized鎖升級過程中只能升級不能降級,起初是JDK早期(1.5之前),是重量級鎖,是找作業系統申請OS鎖。所謂重量級鎖是說獲取鎖和釋放鎖都需要經過作業系統,需要經過相當多的步驟,一旦執行緒或許鎖失敗,整個系統都會陷入阻塞狀態,風險等級很高,雖說synchorized出現異常會自動釋放,但是釋放過程會牽涉到使用者態到核心態之間切換是個效能開銷非常大的操作。
而在JDK1.6之後有了一個無鎖-->偏向鎖-->自旋鎖-->重量級鎖。過程大致內容是:線上程來了之後,先不嘗試對執行緒進行加鎖,只是記錄執行緒的id值,就預設為這個物件是這個執行緒獨有;如果執行緒鎖中已經有執行緒id記錄,則後來的執行緒就會先進行自旋,預設自旋10次,如果依舊拿不著鎖,就會升級為重量級鎖;升級為重量級鎖之後,就會進入waitting區,不再佔用cpu。
鎖的底層標誌
在JVM中,普通物件在記憶體中分為三塊區域:物件頭,例項資料和對齊填充資料。而物件頭包括markword和型別指標,例項資料就是物件的成員變數,padding就是為了保證物件的大小為8位元組的倍數,將物件所佔位元組數補到能被8整除。
其中,一個普通物件有16個位元組,markwork佔8個位元組,型別指標會分情況有不同數量位元組(開啟壓縮指標4位元組,不開啟8位元組,如果是32g以上記憶體,都是8位元組)。
而加鎖其實就是在物件的markwork前兩位二進位制碼設個標記,具體為:00(無鎖),01(偏向鎖),10(自旋鎖),11(OS鎖)
提醒
synchorized鎖方法時,鎖的是this,整個方法;
鎖靜態時,鎖的是.class,整個class檔案;
其中鎖定方法和非鎖定方法可以同時進行。