輕量級鎖和偏向鎖

2021-07-24 19:10:35 字數 1119 閱讀 1921

synchronized會在物件的頭部打標記,這個加鎖的動作是必須要做的,悲觀鎖通常還會做許多其他的指令動作,輕量級鎖希望通過cas實現,它認為通過cas嘗試修改物件頭部的mark區域的內容就可以達到目的,由於mark區域的寬度通常是4~8位元組,也就是相當於乙個int或者long的寬度,是否適合於cas操作。

輕量級鎖通常會做一下4個步驟:

(1) 在棧中分配一塊空間用來做乙份物件頭部mark word的拷貝,在mark word中將物件鎖的二進位制位設定為「未鎖定」(在32位的jvm中通常有2位用於儲存鎖標記,未鎖定的標記為01),這個動作是方便等到釋放鎖的時候將這份資料拷貝到物件頭部。

(2) 通過cas嘗試將頭部的二進位制位修改為「執行緒私有棧中對mark區域拷貝存放的位址」,如果成功,則會將最後2位設定為00,代表已經被輕量級鎖鎖住了。

(3) 如果沒有成功,則判定物件頭部是否已經指向了當前執行緒所在的棧當中,如果成立則代表當前執行緒已經是擁有著,可以繼續執行。

(4) 如果不是擁有著,則說明有多個執行緒在爭用,那麼此時會將鎖公升級為悲觀鎖,執行緒進入blocked狀態。

jvm發現在輕量級鎖裡面多次「重入」和「釋放」時,需要做的判斷和拷貝動作還是很多,而在某些應用程式中,鎖就是被某乙個執行緒一直使用,為了進一步減小鎖的開銷,jvm中出現了偏向鎖,偏向鎖希望記錄的是乙個執行緒id,它比輕量級鎖更加輕量,當再次重入判定時,首先判定物件頭部的執行緒id是不是當前執行緒,若是則表示當前執行緒已經是物件鎖的owner,無須做其他任何動作。

步驟如下:

(1) 乙個執行緒去爭用時,如果沒有其他執行緒爭用,則會嘗試cas去修改mark word中乙個標記為偏向(mark word單獨有乙個bit表示是否可偏向,記錄鎖的位置依然為01),這個cas動作同時會修改mark word部分bit以保留執行緒的id值。

(2) 當執行緒不斷發生重入時,只需要判定頭部的執行緒id是否是當前執行緒,若是,則無需任何操作。

(3) 如果同乙個物件存在另乙個執行緒發起了訪問請求,則首先會判定該物件是否已經被鎖定了。如果已經被鎖定,則會將鎖修改為輕量級鎖(00),也就是鎖粒度上公升了;而如果沒有鎖定,則會將物件的是否可偏向的位置設定為不可偏向。

偏向鎖只是解決了沒有任何鎖爭用的場景,當出現鎖爭用後它便沒有什麼用途了

偏向鎖 輕量級鎖

大多數情況下,不僅不存在多執行緒競爭,而且乙個執行緒會一直去執行乙個同步 塊。基於這種情況,當環境中只有乙個執行緒時,使用無鎖機制 偏向鎖。當某個執行緒獲取到物件的鎖後,會將物件的物件頭設定為 鎖標誌位置為01,偏向鎖標誌為1,偏向執行緒id為當前執行緒的id 並在當前執行緒的棧幀中記錄偏向鎖資訊。...

偏向鎖 輕量級鎖 重量級鎖

首先簡單說下先偏向鎖 輕量級鎖 重量級鎖三者各自的應用場景 偏向鎖 只有乙個執行緒進入臨界區 輕量級鎖 多個執行緒交替進入臨界區 重量級鎖 多個執行緒同時進入臨界區。還要明確的是,偏向鎖 輕量級鎖都是jvm引入的鎖優化手段,目的是降低執行緒同步的開銷。比如以下的同步 塊 synchronized l...

偏向鎖 輕量級鎖 重量級鎖

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