版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第synchronized背后的monitor鎖實(shí)現(xiàn)詳解目錄獲取和釋放monitor鎖的時(shí)機(jī)用javap命令查看反匯編的結(jié)果同步代碼塊同步方法
獲取和釋放monitor鎖的時(shí)機(jī)
本文我們研究下synchronized背后的monitor鎖。
我們都知道,最簡(jiǎn)單的同步方式就是利用synchronized關(guān)鍵字來修飾代碼塊或者修飾一個(gè)方法,那么這部分被保護(hù)的代碼,在同一時(shí)刻就最多只有一個(gè)線程可以運(yùn)行,而synchronized的背后正是利用monitor鎖實(shí)現(xiàn)的。所以首先我們來看下獲取和釋放monitor鎖的時(shí)機(jī),每個(gè)Java對(duì)象都可以用作一個(gè)實(shí)現(xiàn)同步的鎖,這個(gè)鎖也被稱為內(nèi)置鎖或monitor鎖,獲得monitor鎖的唯一途徑就是進(jìn)入由這個(gè)鎖保護(hù)的同步代碼塊或同步方法,線程在進(jìn)入被synchronized保護(hù)的代碼塊之前,會(huì)自動(dòng)獲取鎖,并且無論是正常路徑退出,還是通過拋出異常退出,在退出的時(shí)候都會(huì)自動(dòng)釋放鎖。
我們首先來看一個(gè)synchronized修飾方法的代碼的例子:
publicsynchronizedvoidmethod(){
methodbody
我們看到method()方法是被synchronized修飾的,為了方便理解其背后的原理,我們把上面這段代碼改寫為下面這種等價(jià)形式的偽代碼。
publicvoidmethod(){
rinsicLock.lock();
try{
methodbody
finally{
rinsicLock.unlock();
在這種寫法中,進(jìn)入method方法后,立刻添加內(nèi)置鎖,并且用try代碼塊把方法保護(hù)起來,最后用finally釋放這把鎖,這里的intrinsicLock就是monitor鎖。經(jīng)過這樣的偽代碼展開之后,相信你對(duì)synchronized的理解就更加清晰了。
用javap命令查看反匯編的結(jié)果
JVM實(shí)現(xiàn)synchronized方法和synchronized代碼塊的細(xì)節(jié)是不一樣的,下面我們就分別來看一下兩者的實(shí)現(xiàn)。
同步代碼塊
首先我們來看下同步代碼塊的實(shí)現(xiàn),如代碼所示。
publicclassSynTest{
publicvoidsynBlock(){
synchronized(this){
System.out.println("lagou");
在SynTest類中的synBlock方法,包含一個(gè)同步代碼塊,synchronized代碼塊中有一行代碼打印了lagou字符串,下面我們來通過命令看下synchronized關(guān)鍵字到底做了什么事情:首先用cd命令切換到SynTest.java類所在的路徑,然后執(zhí)行javacSynTest.java,于是就會(huì)產(chǎn)生一個(gè)名為SynTest.class的字節(jié)碼文件,然后我們執(zhí)行javap-verboseSynTest.class,就可以看到對(duì)應(yīng)的反匯編內(nèi)容。
關(guān)鍵信息如下:
publicvoidsynBlock();
descriptor:()V
flags:ACC_PUBLIC
Code:
stack=2,locals=3,args_size=1
0:aload_0
1:dup
2:astore_1
3:monitorenter
4:getstatic#2//Fieldjava/lang/System.out:Ljava/io/PrintStream;
7:ldc#3//Stringlagou
9:invokevirtual#4//Methodjava/io/PrintStream.println:(Ljava/lang/String;)V
12:aload_1
13:monitorexit
14:goto22
17:astore_2
18:aload_1
19:monitorexit
20:aload_2
21:athrow
22:return
從里面可以看出,synchronized代碼塊實(shí)際上多了monitorenter和monitorexit指令,標(biāo)紅的第3、13、19行指令分別對(duì)應(yīng)的是monitorenter和monitorexit。這里有一個(gè)monitorenter,卻有兩個(gè)monitorexit指令的原因是,JVM要保證每個(gè)monitorenter必須有與之對(duì)應(yīng)的monitorexit,monitorenter指令被插入到同步代碼塊的開始位置,而monitorexit需要插入到方法正常結(jié)束處和異常處兩個(gè)地方,這樣就可以保證拋異常的情況下也能釋放鎖
可以把執(zhí)行monitorenter理解為加鎖,執(zhí)行monitorexit理解為釋放鎖,每個(gè)對(duì)象維護(hù)著一個(gè)記錄著被鎖次數(shù)的計(jì)數(shù)器。未被鎖定的對(duì)象的該計(jì)數(shù)器為0,我們來具體看一下monitorenter和monitorexit的含義:
monitorenter
執(zhí)行monitorenter的線程嘗試獲得monitor的所有權(quán),會(huì)發(fā)生以下這三種情況之一:
a.如果該monitor的計(jì)數(shù)為0,則線程獲得該monitor并將其計(jì)數(shù)設(shè)置為1。然后,該線程就是這個(gè)monitor的所有者。
b.如果線程已經(jīng)擁有了這個(gè)monitor,則它將重新進(jìn)入,并且累加計(jì)數(shù)。
c.如果其他線程已經(jīng)擁有了這個(gè)monitor,那個(gè)這個(gè)線程就會(huì)被阻塞,直到這個(gè)monitor的計(jì)數(shù)變成為0,代表這個(gè)monitor已經(jīng)被釋放了,于是當(dāng)前這個(gè)線程就會(huì)再次嘗試獲取這個(gè)monitor。
monitorexitmonitorexit的作用是將monitor的計(jì)數(shù)器減1,直到減為0為止。代表這個(gè)monitor已經(jīng)被釋放了,已經(jīng)沒有任何線程擁有它了,也就代表著解鎖,所以,其他正在等待這個(gè)monitor的線程,此時(shí)便可以再次嘗試獲取這個(gè)monitor的所有權(quán)。
同步方法
從上面可以看出,同步代碼塊是使用monitorenter和monitorexit指令實(shí)現(xiàn)的。而對(duì)于synchronized方法,并不是依靠monitorenter和monitorexit指令實(shí)現(xiàn)的,被javap反匯編后可以看到,synchronized方法和普通方法大部分是一樣的,不同在于,這個(gè)方法會(huì)有一個(gè)叫作ACC_SYNCHRONIZED的flag修飾符,來表明它是同步方法。
同步方法的代碼如下所示。
publicsynchronizedvoidsynMethod(){
對(duì)應(yīng)的反匯編指令如下所示。
publicsynchronizedvoidsynMethod();
descriptor:()V
flags:ACC_PUBLIC,ACC_SYNCHRONIZED
Code:
stack=0,locals=1,args_size=1
0:return
LineNumberTable:
line16:0
可以看出,被synchronized修飾的方法會(huì)有一個(gè)ACC_SYNCHRONIZED標(biāo)志。當(dāng)某個(gè)線程要訪問某個(gè)方法的時(shí)候,會(huì)首先檢查方法是否有ACC_SYNCHRONIZED標(biāo)志,如果有則需要先獲得monitor鎖,然后才能開始執(zhí)行方法,方法執(zhí)行之后再釋放monitor鎖。其他方面,synchronized方法和剛才的synchronized代碼塊是很類似的,例如這時(shí)如果其他線程來請(qǐng)求執(zhí)行方法,也會(huì)因?yàn)闊o法獲得monitor鎖而被阻塞。
好了,本文的內(nèi)容就全部講完了,我們講解了獲取和釋放monitor的時(shí)機(jī),以及被synchronized修飾的等
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- GB/T 24276-2025通過計(jì)算進(jìn)行低壓成套開關(guān)設(shè)備和控制設(shè)備溫升驗(yàn)證的一種方法
- 2025年中職煙草栽培與加工(煙草技術(shù)專題)試題及答案
- 2025年大學(xué)交通運(yùn)輸(物流運(yùn)輸規(guī)劃)試題及答案
- 2025年大學(xué)農(nóng)村電氣技術(shù)(農(nóng)村新能源利用)試題及答案
- 2026年生物科技(基因編輯技術(shù))試題及答案
- 2025年高職獸醫(yī)服務(wù)(服務(wù)技術(shù))試題及答案
- 2025年高職(野生動(dòng)植物資源保護(hù)與利用)野生動(dòng)物監(jiān)測(cè)試題及答案
- 2025年中職護(hù)理(老年護(hù)理)試題及答案
- 2025年高職電網(wǎng)監(jiān)控技術(shù)(電網(wǎng)監(jiān)控操作)試題及答案
- 2025年高職(中藥購(gòu)銷員)中藥銷售綜合測(cè)試題及答案
- 商超信息系統(tǒng)操作規(guī)定
- 如何做好一名護(hù)理帶教老師
- 房地產(chǎn)項(xiàng)目回款策略與現(xiàn)金流管理
- 花溪區(qū)高坡苗族鄉(xiāng)國(guó)土空間總體規(guī)劃 (2021-2035)
- 非連續(xù)性文本閱讀(中考試題20篇)-2024年中考語(yǔ)文重難點(diǎn)復(fù)習(xí)攻略(解析版)
- 專題13 三角函數(shù)中的最值模型之胡不歸模型(原卷版)
- 門診藥房西藥管理制度
- 新能源汽車生產(chǎn)代工合同
- 2025年中煤科工集團(tuán)重慶研究院有限公司招聘筆試參考題庫(kù)含答案解析
- 消防救援預(yù)防職務(wù)犯罪
- 一體化泵站安裝施工方案
評(píng)論
0/150
提交評(píng)論