偏向鎖: HotSpot作者發現,大多數情況下,鎖不僅不存在多線程競爭,而且總是由同一線程多次獲得,爲了讓線程獲取鎖的代價更低,引入了偏向鎖,當一個線程訪問同步塊並獲取鎖時,會在對象頭和棧貞中的鎖記錄裏存儲鎖偏向的線程id,以後該線程進入和退出該同步塊時,不需要進行CAS操作來獲取和釋放鎖,只需簡單的測試一下對象頭的Mark Word裏是否存儲着指向當前線程的偏向鎖,如果測試成功,表明線程已經獲得了該鎖,如果測試失敗,則需再測試一下Mark Word中偏向鎖的標識是否設置爲1(表示當前是偏向鎖),如果沒有設置,則使用CAS來競爭鎖,如果設置了,則嘗試使用CAS將對象頭的偏向鎖指向當前線程.
偏向鎖的撤銷:
偏向鎖使用了一種等到競爭出現才釋放鎖的機制,所以當其他線程嘗試競爭偏向鎖時,
持有偏向鎖的線程纔會釋放鎖。偏向鎖的撤銷,需要等待全局安全點(在這個時間點上沒有正
在執行的字節碼)。它會首先暫停擁有偏向鎖的線程,然後檢查持有偏向鎖的線程是否活着,
如果線程不處於活動狀態,則將對象頭設置成無鎖狀態;如果線程仍然活着,擁有偏向鎖的棧
會被執行,遍歷偏向對象的鎖記錄,棧中的鎖記錄和對象頭的Mark Word要麼重新偏向於其他
線程,要麼恢復到無鎖或者標記對象不適合作爲偏向鎖,最後喚醒暫停的線程。
關閉偏向鎖:
偏向鎖在Java 6和Java 7裏是默認啓用的,但是它在應用程序啓動幾秒鍾之後才激活,如
有必要可以使用JVM參數來關閉延遲:-XX:BiasedLockingStartupDelay=0。如果你確定應用程
序裏所有的鎖通常情況下處於競爭狀態,可以通過JVM參數關閉偏向鎖:-XX:- UseBiasedLocking=false,那麼程序默認會進入輕量級鎖狀態。