一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

synchronized底層揭秘

 HUC王子 2020-11-30

前言

上篇文章我們從硬件級(jí)別探索,對(duì)可見(jiàn)性和有序性的認(rèn)識(shí)上升了一個(gè)高度,卻遲遲沒(méi)有介紹原子性的解決方案。

今天我們就來(lái)聊一聊原子性的解決方案,。

引入鎖機(jī)制,除了可以保證原子性,同時(shí)也可以保證可見(jiàn)性和有序性。

相信小伙伴們對(duì)于synchronized互斥鎖一定很熟悉,但是你懂它的實(shí)現(xiàn)原理嗎,今天就讓我們一起來(lái)揭開(kāi)它的神秘面紗吧。


synchronized的原子性

首先我們來(lái)看一下synchronized是怎么保證原子性的。

其實(shí)往最簡(jiǎn)單了解釋,還是比較容易理解的。synchronized加鎖主要靠的是monitor,monitor在java里可以理解成一個(gè)監(jiān)視器,在操作系統(tǒng)里它又被稱為管程。

簡(jiǎn)單的模型如下圖:

當(dāng)我們的程序通過(guò)synchronized鎖定一個(gè)對(duì)象的時(shí)候,這個(gè)對(duì)象會(huì)關(guān)聯(lián)一個(gè)monitor,獲取鎖時(shí)會(huì)對(duì)monitor中的計(jì)數(shù)器進(jìn)行+1操作,釋放鎖的時(shí)候進(jìn)行-1操作,同時(shí)也是支持可重入的,同一個(gè)線程再次獲取該對(duì)象的鎖,計(jì)數(shù)器就再+1。

如果計(jì)數(shù)器為0就代表完全釋放了鎖,其他線程可以獲取鎖。

如果線程調(diào)用了wait方法,會(huì)釋放鎖資源,同時(shí)把線程放入waitset中,等待notifyall方法喚醒,喚醒后重新開(kāi)始競(jìng)爭(zhēng)鎖資源。

這就是sychronized鎖的最簡(jiǎn)單的解釋,我們當(dāng)然不會(huì)滿足于此,接下來(lái)我們繼續(xù)深入研究一下。

先看一段代碼:

MyLock lock = new MyLock();//一個(gè)自定義的鎖對(duì)象
sychronized(lock){
//...
}

java的對(duì)象在內(nèi)存中存儲(chǔ)的布局可以分為三塊區(qū)域:對(duì)象頭(Header)、實(shí)例數(shù)據(jù)(Instance Data)和對(duì)齊填充(Padding)。

對(duì)象頭包含Mark Word(包含hashcode、鎖數(shù)據(jù)、GC信息等)和Class MetaData Address(指向Class對(duì)象的指針)。

實(shí)例數(shù)據(jù)就是我們?cè)趯?duì)象里存放的那些數(shù)據(jù)。

java要求對(duì)象大小為8字節(jié)的整數(shù)倍,對(duì)齊填充就是用來(lái)填充字節(jié)的,沒(méi)有其他意義。

Mark Word會(huì)指向一個(gè)monitor,這個(gè)monitor是C++實(shí)現(xiàn)的一個(gè)Object Monitor對(duì)象,首先線程在獲取鎖時(shí),先進(jìn)入到entry list中,然后通過(guò)CAS對(duì)count計(jì)數(shù)器進(jìn)行+1操作,如果+1成功代表獲取到鎖,此時(shí)就會(huì)把該線程的信息放入owner中,owner就是用來(lái)存儲(chǔ)當(dāng)前獲取到鎖的線程的。整體結(jié)構(gòu)如圖所示:

 


sychronized的可見(jiàn)性

在說(shuō)可見(jiàn)性之前,我們先引入兩個(gè)概念:Store屏障和Load屏障。

Store屏障就是強(qiáng)制CPU執(zhí)行flush操作,Load屏障就是強(qiáng)制CPU執(zhí)行refresh操作。

flush和refresh我們上篇文章已經(jīng)說(shuō)過(guò),這里就不再解釋了。

那sychronized是如何實(shí)現(xiàn)可見(jiàn)性的呢,其實(shí)就是利用了內(nèi)存屏障。如下:

sychronized(this){
   // monitorenter
   // Load內(nèi)存屏障
   //...  
}
//monitorexit
//Store內(nèi)存屏障

sychronized的有序性

同樣在說(shuō)有序性之前引入兩個(gè)新的內(nèi)存屏障:Acquire屏障和Release屏障。

Acquire屏障可以禁止讀操作和其他讀寫(xiě)操作之間發(fā)生指令重排,Release屏障可以禁止寫(xiě)操作和其他讀寫(xiě)操作之間發(fā)生指令重排。

那sychronized是如何實(shí)現(xiàn)有序性的呢,其實(shí)就是利用了這兩個(gè)內(nèi)存屏障。如下:

sychronized(this){
   // monitorenter
   // Load內(nèi)存屏障
   // Acquire內(nèi)存屏障
   //...  
   //Release內(nèi)存屏障
}
 //monitorexit
 //Store內(nèi)存屏障

需要注意的是Acquire屏障和Release屏障保證的是sychronized內(nèi)部的代碼不會(huì)與外部的代碼之間發(fā)生指令重排,內(nèi)部的代碼自己還是可能發(fā)生指令重排的。


sychronized的鎖優(yōu)化

jdk1.6后jvm對(duì)sychronized進(jìn)行了鎖優(yōu)化,這部分我們做個(gè)概念了解就可以了。

1.鎖消除

鎖消除是JIT編譯器對(duì)sychronized的優(yōu)化,在編譯的時(shí)候會(huì)通過(guò)逃逸分析技術(shù),來(lái)分析鎖對(duì)象。如果只有一個(gè)線程來(lái)加鎖和解鎖,沒(méi)有鎖競(jìng)爭(zhēng),那就沒(méi)有必要加鎖,會(huì)去掉monitorenter和monitorexit指令。

2.鎖粗化

這個(gè)意思是,如果有多個(gè)連續(xù)的加鎖釋放鎖操作,那么編譯后會(huì)變成一把鎖。

例如

sychronized(this){}

sychronized(this){}

sychronized(this){}

連著三個(gè)加鎖操作,編譯后會(huì)變成一個(gè)。

3.偏向鎖

偏向鎖主要是為了減少monitorenter和monitorexit指令的CAS操作,減少開(kāi)銷,如果認(rèn)為當(dāng)前鎖大概率只有一個(gè)線程來(lái)競(jìng)爭(zhēng),那么就會(huì)給這個(gè)鎖維護(hù)好一個(gè)偏好Bias,之后該線程加鎖和釋放鎖都通過(guò)這個(gè)Bias來(lái)執(zhí)行,不需要去執(zhí)行CAS了。

但是如果發(fā)現(xiàn)有其他線程來(lái)競(jìng)爭(zhēng)鎖,就會(huì)收回之前分配好的偏好。

4.輕量級(jí)鎖

如果偏向鎖沒(méi)能實(shí)現(xiàn),也就是說(shuō)有多個(gè)線程競(jìng)爭(zhēng)鎖,那么就會(huì)采用輕量級(jí)鎖。

其實(shí)就是將對(duì)象里的輕量級(jí)鎖指針指向一個(gè)已經(jīng)獲取了鎖的線程,然后判斷一下是不是自己加的鎖,如果是就直接執(zhí)行,如果不是說(shuō)明有其他線程加了鎖,就會(huì)升級(jí)為重量級(jí)鎖,重量級(jí)鎖流程我們上文中介紹原子性的時(shí)候已經(jīng)說(shuō)過(guò)了。

5.適應(yīng)性自旋鎖

在許多場(chǎng)景中,同步資源的鎖定時(shí)間很短,為了這一小段時(shí)間去切換線程,線程掛起和恢復(fù)的花費(fèi)可能會(huì)讓系統(tǒng)得不償失。為了讓當(dāng)前線程“稍等一下”,我們需讓當(dāng)前線程進(jìn)行自旋。

如果在自旋完成后前面鎖同步資源的線程已經(jīng)釋放了鎖,那么當(dāng)前線程就可以不必阻塞而是直接獲取同步資源,從而避免了切換線程的開(kāi)銷。這就是自旋鎖。

適應(yīng)性自旋鎖意味著自旋的時(shí)間(次數(shù))不再固定,而是由前一次在同一個(gè)鎖上的自旋時(shí)間及鎖的擁有者的狀態(tài)來(lái)決定。


總結(jié)

到這里,有關(guān)synchronized的底層實(shí)現(xiàn)我們基本上已經(jīng)聊完了。

使用鎖來(lái)保證原子性,使用內(nèi)存屏障來(lái)保證可見(jiàn)性和有序性。

同時(shí)jvm又對(duì)sychronized做了一些優(yōu)化。

相信小伙伴們理解了本文的內(nèi)容,會(huì)收獲頗豐。

那我們下次再見(jiàn)。

    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多

    熟女白浆精品一区二区| 东京干男人都知道的天堂| 午夜福利视频六七十路熟女| 经典欧美熟女激情综合网| 少妇人妻无一区二区三区| 激情亚洲一区国产精品久久| 亚洲中文字幕高清视频在线观看| 午夜福利视频偷拍91| 成人国产激情福利久久| 国产精品欧美一区两区| 国产精品香蕉在线的人| 这里只有九九热精品视频| 男人和女人干逼的视频| 成人午夜视频精品一区| 好吊色欧美一区二区三区顽频| 色婷婷国产精品视频一区二区保健| 日韩精品一区二区亚洲| 日本办公室三级在线观看| 99秋霞在线观看视频| 日韩中文字幕视频在线高清版| 亚洲av成人一区二区三区在线| 午夜福利直播在线视频| 在线观看免费午夜福利| 国产一区欧美午夜福利| 久久精品国产亚洲熟女| 精品少妇一区二区视频| 成在线人免费视频一区二区| 欧美一区日韩一区日韩一区| 日本人妻精品有码字幕| 日韩高清毛片免费观看| 国产熟女一区二区不卡| 免费国产成人性生活生活片| 国产永久免费高清在线精品| 亚洲男女性生活免费视频| 成人精品视频一区二区在线观看| 69久久精品亚洲一区二区| 日韩成人动画在线观看 | 黄片免费观看一区二区| 日韩蜜桃一区二区三区| 老富婆找帅哥按摩抠逼视频| 99久久精品久久免费|