偏向鎖 輕量級鎖 重量級鎖

2021-09-28 10:28:00 字數 1109 閱讀 8313

首先簡單說下先偏向鎖、輕量級鎖、重量級鎖三者各自的應用場景:

偏向鎖:只有乙個執行緒進入臨界區;

輕量級鎖:多個執行緒交替進入臨界區;

重量級鎖:多個執行緒同時進入臨界區。

還要明確的是,偏向鎖、輕量級鎖都是jvm引入的鎖優化手段,目的是降低執行緒同步的開銷。比如以下的同步**塊:

synchronized (lockobject)

上述同步**塊中存在乙個臨界區,假設當前存在thread#1和thread#2這兩個使用者執行緒,分三種情況來討論:

情況一:只有thread#1會進入臨界區;

情況二:thread#1和thread#2交替進入臨界區;

情況三:thread#1和thread#2同時進入臨界區。

上述的情況一是偏向鎖的適用場景,此時當thread#1進入臨界區時,jvm會將lockobject的物件頭mark word的鎖標誌位設為「01」,同時會用cas操作把thread#1的執行緒id記錄到mark word中,此時進入偏向模式。所謂「偏向」,指的是這個鎖會偏向於thread#1,若接下來沒有其他執行緒進入臨界區,則thread#1再出入臨界區無需再執行任何同步操作。也就是說,若只有thread#1會進入臨界區,實際上只有thread#1初次進入臨界區時需要執行cas操作,以後再出入臨界區都不會有同步操作帶來的開銷。

然而情況一是乙個比較理想的情況,更多時候thread#2也會嘗試進入臨界區。若thread#2嘗試進入時thread#1已退出臨界區,即此時lockobject處於未鎖定狀態,這時說明偏向鎖上發生了競爭(對應情況二),此時會撤銷偏向,mark word中不再存放偏向執行緒id,而是存放hashcode和gc分代年齡,同時鎖標識位變為「01」(表示未鎖定),這時thread#2會獲取lockobject的輕量級鎖。因為此時thread#1和thread#2交替進入臨界區,所以偏向鎖無法滿足需求,需要膨脹到輕量級鎖。

再說輕量級鎖什麼時候會膨脹到重量級鎖。若一直是thread#1和thread#2交替進入臨界區,那麼沒有問題,輕量鎖hold住。一旦在輕量級鎖上發生競爭,即出現「thread#1和thread#2同時進入臨界區」的情況,輕量級鎖就hold不住了。 (根本原因是輕量級鎖沒有足夠的空間儲存額外狀態,此時若不膨脹為重量級鎖,則所有等待輕量鎖的執行緒只能自旋,可能會損失很多cpu時間)

偏向鎖 輕量級鎖 重量級鎖

synchronized關鍵字就像是汽車的自動檔,現在詳細講這個過程。一腳油門踩下去,synchronized會從無鎖公升級為偏向鎖,再公升級為輕量級鎖,最後公升級為重量級鎖,就像自動換擋一樣。那麼自旋鎖在 呢?這裡的輕量級鎖就是一種自旋鎖。初次執行到synchronized 塊的時候,鎖物件變成偏...

輕量級鎖,偏向鎖,重量級鎖

物件頭資訊 使用monitor物件來實現重量級鎖,如果使用重量級鎖,加鎖過程就需要先去關聯monitor物件,然後還需要各種判斷。asychronized關鍵字實現重量級鎖的原理 monitorenter和monitorexit就是操作monitor物件,會有效能損耗,所以引入輕量級鎖。當出現重量級...

偏向鎖,輕量級鎖,重量級鎖(java)

輕量級鎖是jdk 1.6之中加入的新型鎖機制,它名字中的 輕量級 是相對於使用作業系統互斥量來實現的傳統鎖而言的,因此傳統的鎖機制就稱為 重量級 鎖。首先需要強調一點的是,輕量級鎖並不是用來代替重量級鎖的,它的本意是在沒有多執行緒競爭的前提下,減少傳統的重量級鎖使用作業系統互斥量產生的效能消耗。要理...