天天看點

【趣話程式設計】一個Java對象的回憶錄:那些被鎖住的日子

原文連結

偏向鎖

“喂,别動啊,讓我檢查下你的lock位狀态”,不知什麼時候我竟然又睡着了,睜開眼睛,一位線程大哥正蹲在我的旁邊,摸着我頭上的MarkWord。

【趣話程式設計】一個Java對象的回憶錄:那些被鎖住的日子

“lock位是

01

,不錯不錯,讓我再看看偏向鎖标記位,哇,是

1

,太棒了,支援偏向鎖!最後再看看thread位,是0!awesome!看來我來的比較早,還沒人跟我搶”,這位線程大哥嘴裡一直念叨,我也不知道他在說些什麼。

【趣話程式設計】一個Java對象的回憶錄:那些被鎖住的日子

“來,把你的MarkWord給我,我給你一個新的“,線程大哥手裡握着一個64bit的數字,一邊說,一邊準備來把我頭上的MarkWord換掉。

這個時候,我想起小A曾經給我說的話,一下子躲開了,“你要幹嘛”,我緊張的問到。

“小朋友别緊張,我是3001号線程,執行到了

synchronized

代碼塊,需要給你這個對象加下

偏向鎖

。來,聽話,把MarkWord給我”,一邊說一邊帶着邪魅的微笑。

“我的MarkWord不能給你随便改,改壞了怎麼辦”

“别怕,一會兒用完了我會給你恢複的”

我将信将疑,知道胳膊拗不過大腿,隻好把頭伸了過去,“你動手吧”

線程大哥執行了一個CAS操作,把我的MarkWord交換了,然後高高興興的離開了。

[為防抄襲,手動插入文字水印,敬請諒解。本文來自微信公衆号:程式設計技術宇宙]

重偏向

過了一小會兒,又來了一個線程小姐姐。

“Hi,小朋友你好,我是3002号線程,現在我要來鎖定你,讓我檢查下你的lock位狀态吧”,這個線程小姐姐聲音很溫柔。

【趣話程式設計】一個Java對象的回憶錄:那些被鎖住的日子

01

,Good!讓我再看看偏向鎖标記位,呀!是個

1

,糟糕”,小姐姐皺起了眉頭。

“發生什麼事了?”我開口問到。

“被3001号線程那家夥搶在前頭了,把你給鎖定了”

“咦,你怎麼知道3001号線程來過”

“你的MarkWord裡面高54位記錄了他的線程指針,指向的就是3001那家夥”,小姐姐指了指我的頭說到。

我看了看,果然如此,“您别着急,3001号線程大哥說了,一會兒用完會給我恢複的,要不您稍等一會,坐下休息休息?”

“不用了,我又檢查了下,3001号小子已經退出同步塊代碼了,我可以重偏向,這下你是我的了!哈哈”,說完,又把我的MarkWord換了,我看了下,thread字段這次指向了她。

随後的一段時間裡,3001号線程大哥和3002号線程小姐姐來來回回給我鎖了好幾次,不過每次都錯開了時間,一直沒什麼沖突,直到······

輕量級鎖

“糟糕!”,3002号線程小姐姐又來了。

“怎麼了?”

“這一回3001這小子還在執行

synchronized

中的代碼,我沒法重偏向了”,小姐姐有點不開心的樣子。

“那怎麼辦呢?”,我弱弱的問到。

小姐姐沒有理我,在一旁忙碌着。

“總算弄好了,我剛向内務總管線程VMThread送出申請,把偏向鎖更新成輕量級鎖”,說完小姐姐擦了擦額頭的汗。

話音剛落,VMThread大爺就來了,他也伸手準備要換我的MarkWord。

【趣話程式設計】一個Java對象的回憶錄:那些被鎖住的日子

“啊,不行,我被3001号線程大哥鎖住了,MarkWord裡面寫着他的位址呢,你可不要亂改啊”,說完我躲到了一邊。

“孩子别怕,3001号線程現在在

安全點

,被挂起來了,現在有别人也要來鎖定你,偏向鎖不夠用了,咱得更新成輕量級鎖。”,VMThread大爺一臉慈祥的說到。

“你們這樣背着3001号線程私自改了不會出問題嗎?”,我還是有點擔心。

“别擔心,隻是更新一下,并不會改變你的歸屬。看到3001号線程的棧了嗎,我在那裡申請到了一個LockRecord,會把你的MarkWord儲存過去,LockRecord中的Obj也會指向你。”,大爺繼續說道。

“那需要我做什麼呢?”

“來,我給你換一個新的MarkWord”,說完就又給我換掉了。我看了一下,lock位變成了

00

,剩下的位變成了一個指針,剛好指向了他剛剛說的那個LockRecord

【趣話程式設計】一個Java對象的回憶錄:那些被鎖住的日子

VMThread大爺走後,3002号線程小姐姐開始我旁邊轉來轉去,每過一會兒過來看一眼,就這樣來來回回好幾次,我終于忍不住了。

“你這是在幹嘛啊,在我面前晃來晃去,我頭都暈了”

【趣話程式設計】一個Java對象的回憶錄:那些被鎖住的日子

“我這是在自旋,等3001号那家夥來釋放,話說那家夥怎麼還不來”,小姐姐說完看了一眼手裡的計數器。

重量級鎖

“不行了,不能再等了,白白讓我浪費了這麼多時間”,小姐姐等得有些生氣,“來,我再給你換個MarkWord”

“這怎麼又要換了?”,我有點納悶兒。

“那家夥久等不來,我不能一直這麼等着,占着CPU不幹活啊,得給你膨脹成重量級鎖”,說完,小姐姐又執行了一個CAS操作,把我的MarkWord修改了。

我看了一下,這一次,lock位變成了

10

,剩下的位指向的地方好像不是一個LockRecord。

【趣話程式設計】一個Java對象的回憶錄:那些被鎖住的日子

“小姐姐,我這MarkWord中指向的是個什麼啊?”,我忍不住問到。

“那是一個ObjectMonitor對象,哦,也就是我說的重量級鎖啊”,一邊說,一邊準備了一個ObjectWaiter對象,把自己線程位址放了進去,随後将這個對象放入monitor對象的等待清單中。

“小姐姐,為什麼要叫重量級鎖呢?”

“因為一會兒我就得去線程切換,交出占用的CPU,讓給别人,等你被釋放之後我再來,這一來一去的挺折騰的,是以叫重量級鎖嘛。好了,小朋友,我得去休息了,回頭見”,說完就離開了。

hashcode

小姐姐前腳剛走,又雙叒來了一個線程大叔。

“你是不是也要來鎖定我啊?”,這一次我先開口了。

“小朋友,你誤會了,我要計算下你的HashCode,等下要放到你的MarkWord中”,大叔蹲在一旁手裡計算着什麼。

【趣話程式設計】一個Java對象的回憶錄:那些被鎖住的日子

“怎麼又要放在MarkWord裡,你們就不能換個地方存嗎?”,我有點不耐煩了。

“你為什麼要說又呢”,大叔問到。

“剛才有幾個線程把我的MarkWord改了又改,現在你又要來...”

聽完我的話,大叔停下了手裡的計算,湊近了看了看我的MarkWord,“呀!lock位是

10

,你被鎖了啊,沒事兒,我可以把HashCode儲存在ObjectMonitor裡面,好了,你繼續玩吧,我就不打擾你了”

大叔說完轉身離開,留下我獨自一個對象,不多時我又睡着了~

未完待續······

彩蛋

不知怎麼回事,3001号線程大哥始終未曾過來将我釋放,時間就這樣一分一秒的流逝。

直到3003号線程的到來,才知道發生了什麼······

預知後事如何,請關注後續精彩······

來源 | 程式設計技術宇宙

作者 | 軒轅之風