Java鎖升級的實現(xiàn)過程
對象內(nèi)存布局
Java對象在內(nèi)存中存儲的布局可以分為3塊區(qū)域: 對象頭、實例數(shù)據(jù)、對齊填充。
對象頭,分為兩個部分,第一個部分存儲對象自身的運行時數(shù)據(jù),又稱為Mark Word
,32位虛擬機占32bit,64位虛擬機占64bit。如圖所示,不同鎖狀態(tài)下,Mark Word的結(jié)構(gòu),理解下面要介紹的各種鎖,和鎖升級過程,都需要先充分了解Mark Word
的結(jié)構(gòu)。
第二部分是類型指針,指向類元數(shù)據(jù)指針,虛擬機通過此指針,確定該對象屬于那個類的實例。
輕量級鎖
輕量級鎖是相對于重量級鎖(Synchrnoized
)而言的,本意是在沒有多線程競爭的前提下,減少傳統(tǒng)的重量級鎖使用操作系統(tǒng)互斥量產(chǎn)生的性能消耗。
輕量級鎖的獲取
線程進入同步塊時,如果此同步對象沒有被鎖定(即鎖標志位為01
,是否為偏向鎖為0
),虛擬機在當前線程的棧幀中建立一個名為鎖記錄(Lock Record)的空間,用于存儲鎖對象目前的一個Mark Word
的copy
然后虛擬機使用CAS操作,嘗試將Mark World
更新為指向Lock Record
的指針,如果更新成功,那么線程擁有了該對象的鎖,并且將鎖標志位置位00
,如圖所示
一旦有兩條以上的線程搶占該鎖,輕量級鎖會升級為重量級鎖。鎖標志位置為10
,Mark Word存儲的就是指向重量級鎖的指針
輕量級鎖釋
- 放如果對象的Mark Word仍然指向著線程的鎖記錄, 那就用CAS操作把對象當前的Mark Word和線程中復制的Displaced Mark Word替換回來, 如果替換成功, 整個同步過程就完成了。
- 如果替換失敗, 說明有其他線程嘗試過獲取該鎖,輕量級鎖膨脹為重量級鎖,那就要在釋放鎖的同時, 喚醒被掛起的線程。
偏向鎖
引入偏向鎖的目的是在沒有多線程競爭的前提下,進一步減少線程同步的性能消耗。
偏向鎖的獲取
開啟偏向鎖模式后,鎖第一次被線程獲取的時候,虛擬機會把對象頭中是否為偏向鎖
的標志位設(shè)位0
,同時使用CAS操作把獲取到這個鎖的線程的ID記錄在對象的Mark Word之中。
當有另外一個線程去嘗試獲取這個鎖時, 偏向模式就宣告結(jié)束。 根據(jù)鎖對象目前是否處于被鎖定的狀態(tài), 撤銷偏向( Revoke Bias) 后恢復到未鎖定( 標志位為“01”)或輕量級鎖定( 標志位為“00”) 的狀態(tài)
偏向鎖的釋放
偏向鎖,并沒有顯式的鎖釋放過程,主要依靠鎖的批量再偏向(Bulk Rebias)機制實現(xiàn)鎖釋放。
該機制的主要工作原理如下:
- 引入一個概念 epoch, 其本質(zhì)是一個時間戳 , 代表了偏向鎖的有效性,從前文描述的對象頭結(jié)構(gòu)中可以看到, epoch 存儲在可偏向?qū)ο蟮?MarkWord 中。
- 除了對象中的 epoch, 對象所屬的類 class 信息中, 也會保存一個 epoch 值,每當遇到一個全局安全點時, 如果要對 class 進行批量再偏向, 則首先對 class 中保存的 epoch 進行增加操作, 得到一個新的 epoch_new
- 然后掃描所有持有 class 實例的線程棧,根據(jù)線程棧的信息判斷出該線程是否鎖定了該對象, 僅將epoch_new 的值賦給被鎖定的對象中。
- 退出安全點后, 當有線程需要嘗試獲取偏向鎖時, 直接檢查 class中存儲的 epoch 值是否與目標對象中存儲的 epoch 值相等,如果不相等, 則說明該對象的偏向鎖已經(jīng)無效了, 可以嘗試對此對象重新進行偏向操作。
整個鎖升級過程
參考文章
到此這篇關(guān)于Java鎖升級的實現(xiàn)過程的文章就介紹到這了,更多相關(guān)Java鎖升級內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java編程中使用XFire框架調(diào)用WebService程序接口
這篇文章主要介紹了Java編程中使用XFire調(diào)用WebService程序接口的方法,WebService是一種跨編程語言和跨操作系統(tǒng)平臺的遠程調(diào)用技術(shù),需要的朋友可以參考下2015-12-12Spring?Validation接口入?yún)⑿r炇纠a
Spring?Validation是一種用于實現(xiàn)數(shù)據(jù)校驗的框架,它提供了一系列的校驗器,針對不同的數(shù)據(jù)類型可以使用不同的校驗器進行校驗,下面這篇文章主要給大家介紹了關(guān)于Spring?Validation接口入?yún)⑿r灥南嚓P(guān)資料,需要的朋友可以參考下2023-06-06解決Spring security5.5.7報錯Encoded password does
這篇文章主要介紹了解決Spring security5.5.7出現(xiàn)Encoded password does not look like BCrypt異常問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-08-08SpringMVC 參數(shù)綁定之視圖傳參到控制器的實現(xiàn)代碼
這篇文章主要介紹了SpringMVC 參數(shù)綁定之視圖傳參到控制器的相關(guān)知識,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-03-03Springboot使用@Valid 和AOP做參數(shù)校驗及日志輸出問題
這篇文章主要介紹的Springboot使用@Valid 和AOP做參數(shù)校驗及日志輸出問題,本文通過代碼講解的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2019-11-11Java深入淺出掌握SpringBoot之MVC自動配置原理篇
在進行項目編寫前,我們還需要知道一個東西,就是SpringBoot對我們的SpringMVC還做了哪些配置,包括如何擴展,如何定制,只有把這些都搞清楚了,我們在之后使用才會更加得心應(yīng)手2021-10-10springBoot的事件機制GenericApplicationListener用法解析
這篇文章主要介紹了springBoot的事件機制GenericApplicationListener用法解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值的相關(guān)資料2019-09-09