偏向鎖
JVM默認開啟偏向鎖。在對象頭中鎖標志前一位用來標記偏向鎖是否可用。
鎖標記01表示偏向鎖。
偏向鎖釋放
獲得偏向鎖的線程,在對象頭中寫有線程id,不會主動釋放鎖:
- 沒有其他線程競爭,對象頭中始終是獲得鎖的tid。
- 線程tid2競爭,此時objhead中仍存着tid1。JVM首先安全暫停tid1,判斷tid1是否仍處於同步塊,如果是,那么需要升級鎖;如果不是,說明tid1不需要鎖了,objhead中的tid字段置零——釋放鎖。線程可以再次競爭偏向鎖。
偏向鎖就是這個意思,偏向已經獲取到鎖的線程,默認不釋放,只有競爭發生時,才有釋放鎖的可能,如果此時仍然需要鎖定,那么競爭失敗,可以認定線程競爭比較頻繁,因此,需要升級鎖。
CAS
CAS是獲取鎖的關鍵操作,大概是boolean CAS(objhead.tid,markword,selftid_markword)這樣的方法,其中markword是未加鎖狀態的markword,主要是測試鎖標記為01時,objhead是否無鎖(tid==0),如果是,則設置自己的tid,表明加鎖。
鎖的本質是一個狀態量,競爭鎖的關鍵點在於檢查狀態和設置狀態是原子完成的。
輕量級鎖
自旋5000次
占用鎖的線程在同步代碼結束后,使用cas釋放鎖,當有競爭時,此時的鎖標記已經被競爭者修改為重量級鎖10,cas操作失敗,有鎖線程繼續按照新的鎖標記釋放鎖,此時多線程按照重量級鎖競爭。