Synchronized 鎖公升級機制

2021-10-24 22:42:28 字數 970 閱讀 3148

1.6 之前的 synchronized 都是 "重量級鎖",什麼是重量級鎖呢?就是乙個執行緒在獲取到 cpu 排程後,開始執行 synchronized 修飾的**塊,這時其他執行到這裡的執行緒必須進行一次 "上下文切換"(下面有解釋)(其實在進行上下文切換前會先嘗試獲取鎖資源,失敗才會進行"上下文切換",這是非公平鎖的特性,下面 lock 部分有講解,這裡比較的是 synchronized 效率問題,所以忽略一開始就搶奪到鎖資源的情況)和 "加鎖 "、"解鎖" 操作。這就是 "重量級鎖",這樣的鎖有嚴重的弊端。"上下文切換" 和 "加鎖"、 "解鎖" 這些動作雖然在單執行緒下消耗的時間並不算多,但是在一些高併發場景,例如百萬、千萬併發的場景,那麼這些動作消耗的總時間就比較大了;另外一種情況就是某段**可能發生多個執行緒搶占執行的情況,但是實際並沒有發生這種情況,都是乙個執行緒執行完後下乙個執行緒才執行到這段**,這樣 "加鎖"、解鎖" 消耗的時間就浪費了。那麼有什麼方法去解決這個問題呢,這就是鎖公升級機制帶來的好處。

上下文切換:執行緒之間的切換需要前乙個執行緒先儲存當前的狀態,然後進入 "睡眠" 狀態,然後下乙個執行緒 "啟動",執行,等到下一次前乙個執行緒獲取到 cpu 排程時,再去讀取上次儲存的狀態,然後 "啟動"。我們把乙個執行緒從儲存當前狀態到下一次"啟動"完成稱作這個執行緒的一次 "上下文切換"。

synchronized 鎖公升級機制是從偏向鎖->輕量級鎖->重量級鎖 ,這個過程是不可逆的。

在具體說這三種鎖時,先要了解物件頭的 mark word 部分,我們都知道物件上儲存著這個物件的一切資訊,包括它的位址、內部方法、屬性等資訊,前面說過監視器,就是乙個鎖對應著乙個物件,所以在物件上也儲存著這個物件所關聯鎖的資訊。關於鎖的資訊就儲存在物件物件頭的 mark word 部分上。下面是 mark word 結構示意圖:

下面說得偏向鎖、輕量級鎖、重量級鎖都會用到這上面的字段。

synchronized鎖的公升級

在分析markword時,提到了偏向鎖 輕量級鎖 重量級鎖。在分析這幾種鎖的區別時,我們先來思考乙個問題 使用鎖能夠實現資料的安全性,但是會帶來效能的下降。不使用鎖能夠基於執行緒並行提公升程式效能,但是卻不能保證執行緒安全性。這兩者之間似乎是沒有辦法達到既能滿足效能也能滿足安全性的要求。hotspo...

synchronized與鎖公升級

當乙個共享資源有可能被多個執行緒同時訪問並修改的時候,需要用鎖來保證資料的正確性。請看下圖 執行緒a和執行緒b分別往同乙個銀行賬戶裡面新增貨幣,a執行緒從記憶體中讀取 read 當前賬戶金額 0 到執行緒a的本地棧,進行 100的操作後,這時b執行緒也從記憶體中讀取當前金額 0 到執行緒b的本地棧,...

synchronized的鎖公升級原理

無鎖狀態 偏向鎖 輕量級鎖 自旋鎖 重量級鎖 乙個物件一開始建立出來的時候是通常是偏向鎖狀態 當有另乙個執行緒來競爭的時候,就會公升級為輕量級鎖。競爭的2個執行緒會使用cas爭搶將自己執行緒棧中的lock record位址寫入物件頭的markword中。誰先寫成功,誰就獲得鎖。沒成功的就會不斷的自旋...