synchronized 各種鎖狀態

偏向鎖的論文中給出的,偏向鎖定下的鎖狀態轉換:
狀態轉換
關於偏向鎖的原始論文,可以參考:HotSpot 偏向鎖,原始論文翻譯
可能發生的所有狀態轉換:
對象可能的初始鎖狀態只有 可偏向鎖無鎖 兩種。
註釋:可偏向狀態,使用原始論文裏的表達就是 the biasable but unbiased state。又叫 匿名偏向狀態,後面統一使用 可偏向狀態表達。

可偏向鎖 可以變成 偏向鎖,也可以撤銷爲 無鎖偏向鎖 可以批量重偏向爲 可偏向鎖,也可以根據偏向所有者是否正在持有該鎖決定撤銷爲 輕量級鎖 還是 無鎖
ps:可偏向鎖撤銷爲無鎖的情況爲,需要計算鎖對象的 identity hash code。

無鎖 可以變成 輕量級鎖,也可以直接變成 重量級鎖

輕量級鎖 可以解鎖爲 無鎖,也可以發生鎖爭用後膨脹成 重量級鎖

狀態轉換的細節描述:
牢記,任何時刻都有可能發生鎖爭用。

線程在獲取輕量級鎖時,判斷是否是自己持有該輕量級鎖,如果是,則遞歸鎖定,如果不是則輕量級鎖變重量級鎖。

線程請求獲取處於無鎖狀態的鎖時,先嚐試加輕量級鎖。加鎖成功則無鎖變輕量級鎖,加鎖失敗(說明被其它線程成功加輕量級鎖)則輕量級鎖變重量級鎖。

線程通過加輕量級鎖進入同步代碼塊,在退出同步代碼塊時,首先判斷鎖有沒有膨脹,如果鎖已經膨脹爲重量級鎖,則按重量級鎖的方式解鎖,並通知正在等待獲取該鎖的其他線程。否則嘗試解輕量級鎖,解鎖成功則輕量級鎖變無鎖,解鎖失敗(說明該鎖被其它線程膨脹爲重量級鎖),則按重量級鎖的方式釋放鎖,並通知正在等待獲取該鎖的其他線程。

線程請求獲取處於可偏向但未偏向的鎖時,先嚐試讓鎖偏向自己。偏向成功則可偏向鎖變偏向鎖,偏向失敗(說明偏向了其它線程)則撤銷偏向,如果偏向所有者正在持有該偏向鎖,則偏向鎖變輕量級鎖,如果允許重偏向則偏向鎖變可偏向鎖,否則偏向鎖變無鎖。
註釋:如何判斷偏向所有者是否正在持有偏向鎖?通過遍歷偏向所有者棧中的 鎖記錄 來判斷,如果存在指向該偏向鎖的鎖記錄,則表示偏向所有者正在持有該鎖。

線程請求獲取一個已經偏向於另一個線程的偏向鎖。兩種情況:1. 如果偏向所有者正在持有該鎖,則先把偏向鎖撤銷爲輕量級鎖,然後再膨脹爲重量級鎖。2. 如果偏向所有者沒有持有該鎖,看情況又有兩種選擇,一是重偏向爲自己,二是先把偏向鎖撤銷爲無鎖,然後再嘗試輕量級鎖定。

怎麼把偏向所有者正在持有的鎖撤銷爲輕量級鎖呢?
線程請求偏向鎖時,如果其它線程正在持有該鎖,則需要所有用戶線程走到一個全局安全點,此時用戶線程都被阻塞。VM 線程會遍歷偏向所有者的棧,將所有與該鎖關聯的鎖記錄填充進(偏向所有者如果使用輕量級鎖定,將會產生的)值。接下來,更新對象的 mark word,以指向棧上最早關聯該鎖的鎖記錄。最後,釋放在安全點上被阻塞的線程。
ps:線程的所有鎖記錄存放在棧中一段連續的內存中。線程只要進入同步代碼塊就會關聯一個鎖記錄(鎖記錄指向鎖對象),只要退出同步代碼塊就會釋放一個鎖記錄(鎖記錄指向鎖對象的指針置 NULL)。偏向鎖定時,鎖記錄裏的 displaced mark word 字段爲 NULL。

最後
我認爲理解各種鎖優化針對的場景至關重要。

  1. 自旋鎖:
    場景:很多同步代碼塊的執行時間很短,鎖佔用的時間也很短。
    在這種場景下,線程爭用鎖時,自旋一小段時間比進行系統調用掛起線程代價要小得多。
    自旋時間不能過長,至少不能超過線程切換的時間。否則直接切換線程或掛起線程更划算。
    自旋次數的默認值是 10 次。JDK1.6 引入自適應自旋鎖,自適應自旋鎖可以根據歷史情況調整自旋次數。
    註釋:系統調用會導致用戶態和內核態的切換。爲什麼系統調用比普通的函數調用更耗時?用戶態和內核態切換的代價在哪?
  2. 輕量級鎖:
    場景:在實際程序中,大多數鎖的獲取是沒有爭用的。
    輕量級鎖的目的是,請求鎖時避免直接進行系統調用加重量級鎖。
  3. 偏向鎖:
    場景:大多數監視器不僅是沒有爭用的,而且在它們的生命週期中只有一個線程進入和退出。
    偏向鎖的優化粒度就比較細了,認爲 CAS 原子操作的開銷也很大,其優化的目的是儘可能不使用原子操作。輕量級鎖雖然避免了直接加重量級鎖,但每次加鎖和解鎖時都需要 CAS 操作。而偏向鎖避免了偏向所有者加鎖和解鎖時的 CAS 操作。
  4. 批量重偏向
    場景:在某些情況下,將一組對象重偏向到另一個線程是有好處的,特別是當一個線程分配許多對象並對每個對象執行一個初始同步操作,而另一個線程對這些對象執行後續同步操作時。
  5. 批量撤銷
    場景:某個類的對象頻繁被多個線程加鎖,比如多個線程共享的隊列。
    此時,該類的對象會頻繁發生偏向撤銷,禁用該類的偏向鎖定是應該的。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章