偏向鎖撤銷過程


偏向鎖的 撤銷(revoke)是一個很特殊的操作,為了執行撤銷操作,需要等待全局安全點,此時所有的工作線程都停止了執行。偏向鎖的撤銷操作並不是將對象恢復到無鎖可偏向的狀態,而是在偏向鎖的獲取過程中,發現競爭並且對方並沒有結束釋放偏向鎖時,直接將一個被偏向的對象升級到被加了輕量級鎖的狀態。
由於偏向鎖的移除需要在全局安全點的時候執行,所以如果當有大量線程競爭同一個鎖資源時,我們可以通過關閉偏向鎖來調優系統性能。

https://z.itpub.net/article/detail/B87A9918BBB38652E96040B0C50A87C9

如果需要撤銷的是當前線程,只要遍歷當前線程的棧就能拿到lock record,可以直接調用revoke_bias,不需要等到safe point再撤銷。在調用Object#hashcode時,也會走到該分支將為偏向鎖的鎖對象直接恢復為無鎖狀態。若不是當前線程,會被push到VM Thread中等到safepoint的時候再執行。

VMThread內部維護了一個VMOperationQueue類型的隊列,用於保存內部提交的VM線程操作VM_operation。GC、偏向鎖的撤銷等操作都是在這里被執行。
撤銷調用的revoke_bias方法的代碼就不貼了。大致邏輯是:

步驟 1、查看偏向的線程是否存活,如果已經死亡,則直接撤銷偏向鎖,然后slowenter。JVM維護了一個集合存放所有存活的線程,通過遍歷該集合判斷某個線程是否存活。

步驟 2、偏向的線程是否還在同步塊中,如果不在,則撤銷偏向鎖。如果在同步塊中,執行步驟3。這里是否在同步塊的判斷基於上文提到的偏向鎖的重入計數方式:在偏向鎖的獲取中,每次進入同步塊的時候都會在棧中找到第一個可用(即棧中最高的)的Lock Record,將其obj字段指向鎖對象。每次解鎖的時候都會把最低的Lock Record移除掉,所以可以通過遍歷線程棧中的Lock Record來判斷是否還在同步塊中。輕量級鎖的重入也是基於Lock Record的計數來判斷。

步驟 3、升級為輕量級鎖。將偏向線程所有相關Lock Record的Displaced Mark Word設置為null,再將最高位的Lock Record的Displaced Mark Word 設置為無鎖狀態,然后將對象頭指向最高位的Lock Record。這里沒有用到CAS指令,因為是在safepoint,可以直接升級成輕量級鎖。

從低往高遍歷棧的Lock Record,將obj置為null,最高的設計displace mark word 表示輕量級鎖

https://www.jianshu.com/p/4758852cbff4

======

撤銷偏向鎖就是將鎖對象oop的對象頭恢復成無鎖狀態或者膨脹成輕量級鎖狀態,執行撤銷動作的前提是鎖對象oop的對象頭處於偏向鎖狀態。具體而言有以下幾種情形:

執行Object類的hashcode方法,會將其恢復成無鎖狀態。
執行Object類的wait/notify/notifyall方法,會將其恢復成無鎖狀態,直接膨脹成重量級鎖。
執行jni_MonitorEnter或者jni_MonitorExit方法,會將其恢復成無鎖狀態,直接膨脹成重量級鎖。
執行Unsafe類的monitorenter/trymonitorenter/monitorexit方法,會將其恢復成無鎖狀態,直接膨脹成重量級鎖。
嘗試獲取某個偏向鎖,如果該偏向鎖被某個線程占用了,但是沒有關聯的BasicObjectLock,即實際占用該偏向鎖的方法已經退出了,則會將其恢復成無鎖狀態,然后膨脹成輕量級鎖,但是在撤銷一定次數后觸發批量重偏向(rebasic)的情形下也可能重新獲取該偏向鎖。如果該偏向鎖正在被某個方法所使用,即存在對應的BasicObjectLock,則直接將該偏向鎖膨脹成輕量級鎖。
注意偏向鎖的撤銷大部分情形下都是需要在安全點下執行,因為需要遍歷其他線程的所有調用棧幀,判斷是否存在與之關聯的BasicObjectLock。在以下情形不需要在安全點下執行:

目標對象的對象頭是匿名偏向鎖狀態
目標對象的Klass的prototype_header變成無鎖狀態
目標對象的Klass的prototype_header中的epoch值和目標對象對象頭中的epoch值不一樣
目標對象的偏向鎖由當前線程持有
https://blog.csdn.net/qq_31865983/article/details/105024397


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM