文章目錄
- 鎖升級原理
- 鎖的升級的目的
- 鎖的四種狀態(tài)
- 偏向鎖
- 輕量級鎖
- 重量級鎖
- 輕量級鎖和重量級鎖的對比
- 偏向鎖的設(shè)置
- 自旋鎖自旋多少次競爭不到后會(huì)升級到重量級鎖?
- 為什么有了自旋鎖還需要重量級鎖?
- 偏向鎖是否一定比自旋鎖效率高?
————————————————————————————————————
創(chuàng)新互聯(lián)是一家專業(yè)提供
敘永企業(yè)網(wǎng)站建設(shè),專注與
網(wǎng)站建設(shè)、成都網(wǎng)站制作、
H5高端網(wǎng)站建設(shè)、小程序制作等業(yè)務(wù)。10年已為敘永眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站建設(shè)公司優(yōu)惠進(jìn)行中。鎖升級原理
- 鎖一開始并不是進(jìn)入到重量級狀態(tài),一開始是在推廣階段是偏向鎖,再升級到輕量級鎖,再升級到重量級鎖。在推廣階段請求較少,用偏向鎖就能滿足要求
synchronized鎖升級原理:
在鎖對象的對象頭里面有一個(gè)threadid字段,在第一次訪問的時(shí)候threadid為空, jvm 讓其持有偏向鎖,并將threadid 設(shè)置為其線程id,再次進(jìn)入的時(shí)候會(huì)先判斷。threadid是否與其線程id一致,如果一致則可以直接使用此對象,如果不一致,則升級偏向鎖為輕量級鎖,通過自旋循環(huán)一定次數(shù)來獲取鎖,執(zhí)行一定次數(shù)之后,如果還沒有正常獲取到要使用的對象,此時(shí)就會(huì)把鎖從輕量級升級為重量級鎖!此過程就構(gòu)成了synchronized鎖的升級。
鎖的升級的目的
鎖的升級的目的:
鎖升級是為了減低了鎖帶來的性能消耗。在Java 6之后優(yōu)化 synchronized的實(shí)現(xiàn)方式,使用了偏向鎖升級為輕量級鎖再升級到重量級鎖的方式,從而減低了鎖帶來的性能消耗。
鎖的四種狀態(tài)
上面講到鎖有四種狀態(tài),并且會(huì)因?qū)嶋H情況進(jìn)行膨脹升級,其膨脹方向是:
無鎖——>偏向鎖——>輕量級鎖——>重量級鎖,并且膨脹方向不可逆。
偏向鎖
一句話總結(jié)它的作用: 減少統(tǒng)一線程獲取鎖的代價(jià)。在大多數(shù)情況下,鎖不存在多線程競爭,總是由同一線程多次獲得,那么此時(shí)就是偏向鎖。
- 優(yōu)點(diǎn): 加鎖和解鎖不需要額外的消耗,和執(zhí)行非同步方法相比僅存在納秒級別的差距
- 缺點(diǎn): 如果線程之間存在競爭,會(huì)帶來額外的鎖撤銷的消耗
- 使用場景: 適用于一個(gè)線程訪問同步塊的場景
- 核心思想: 如果一個(gè)線程獲得了鎖,那么鎖就進(jìn)入偏向模式,此時(shí)Mark word的結(jié)構(gòu)也就變?yōu)槠蜴i結(jié)構(gòu),當(dāng)該線程再次請求鎖時(shí),無需再做任何同步操作,即獲取鎖的過程只需要檢查Mark word的鎖標(biāo)記位為偏向鎖以及當(dāng)前線程ID等于Mark word的ThreadID即可,這樣就省去了大量有關(guān)鎖申請的操作。
輕量級鎖
- 輕量級鎖是由偏向鎖升級而來,當(dāng)存在第二個(gè)線程申請同一個(gè)鎖對象時(shí),偏向鎖就會(huì)立即升級為輕量級鎖。
- 注意這里的第二個(gè)線程只是申請鎖,不存在兩個(gè)線程同時(shí)競爭鎖,可以是一前一后地交替執(zhí)行同步塊。
- 自旋: 沒有競爭到資源的鎖,在極短的時(shí)間內(nèi)查看一次資源
- 好處: 加鎖的速度快,能立刻查看到資源被解鎖并加上鎖
- 缺點(diǎn): 沒競爭到資源的線程也會(huì)自旋,會(huì)浪費(fèi)cpu開銷,損害cpu利用率
- 使用場景: 自旋鎖適合線程較少,少量并發(fā)的操作,因?yàn)檫@樣浪費(fèi)的自旋操作少
重量級鎖
- 重量級鎖是由輕量級鎖升級而來,當(dāng)同一時(shí)間有多個(gè)線程競爭鎖時(shí),鎖就會(huì)被升級成重量級鎖,此時(shí)其申請鎖帶來的開銷也就變大。
- 流程: 競爭成功的加鎖,競爭失敗的進(jìn)入阻塞隊(duì)列不參與競爭,cpu全力執(zhí)行競爭成功的任務(wù),這樣cpu利用率比較高;釋放鎖之后會(huì)發(fā)一個(gè)通知,阻塞隊(duì)列的線程出來進(jìn)入就緒隊(duì)列,再一次進(jìn)行競爭,競爭失敗的再進(jìn)入阻塞隊(duì)列。
- 好處: 競爭失敗的不會(huì)浪費(fèi)cpu,并發(fā)量多的時(shí)候,使用重量級鎖,cpu浪費(fèi)率比較低,整體性能更好一些;重量級鎖幾乎很少導(dǎo)致cpu浪費(fèi)
- 缺點(diǎn): 線程阻塞,響應(yīng)時(shí)間慢。
- 使用場景: 適合線程很多,并發(fā)很多,追求吞吐量,同步塊或者同步方法執(zhí)行時(shí)間較長的場景。
輕量級鎖和重量級鎖的對比
- 輕量級鎖競爭的線程不會(huì)阻塞,提高程序響應(yīng)速度;競爭不到線程的鎖也會(huì)自旋,會(huì)消耗cpu;適合追求響應(yīng)時(shí)間快或同步塊執(zhí)行速度快的場景。
- 重量級鎖線程競爭失敗的會(huì)阻塞,不會(huì)自旋,不會(huì)消耗cpu;線程阻塞后,之前競爭成功的線程在鎖釋放后需要通知被阻塞的線程,響應(yīng)時(shí)間變慢;適合追求吞吐量或同步塊執(zhí)行速度較長的場景。
偏向鎖的設(shè)置
開啟偏向鎖的方式:
—個(gè)對象創(chuàng)建時(shí):
- 如果開啟了偏向鎖(默認(rèn)開啟),那么對象創(chuàng)建后,markword值為0x05即最后3位為101,這時(shí)它的thread、epoch、age都為0。
- 偏向鎖是默認(rèn)是延遲的,不會(huì)在程序啟動(dòng)時(shí)立即生效,如果想避免延遲,可以加VM參數(shù)
-xx:BiasedLockingStartupDelay=e
來禁用延遲。 - 如果沒有開啟偏向鎖,那么對象創(chuàng)建后,markword值為0x01即最后3位為001,這時(shí)它的 hashcode,age都為0,第一次用到hashcode時(shí)才會(huì)賦值。
禁用偏向鎖:
VM 參數(shù) -XX:-UseBiasedLocking
特殊情況:
調(diào)用 對象的hashcode方法時(shí),偏向鎖也會(huì)被禁用. 這是因?yàn)檎{(diào)用了對象的 hashCode,但偏向鎖的對象 MarkWord 中存儲(chǔ)的是線程 id(54位),如果調(diào)用 hashCode(31位) 會(huì)導(dǎo)致偏向鎖被撤銷。
撤銷 - 其它線程使用對象:
當(dāng)有其它線程使用偏向鎖對象時(shí),會(huì)將偏向鎖升級為輕量級鎖。
批量撤銷:
當(dāng)撤銷偏向鎖閾值超過 40 次后,jvm 會(huì)這樣覺得,自己確實(shí)偏向錯(cuò)了,根本就不該偏向。于是整個(gè)類的所有對象 都會(huì)變?yōu)椴豢善虻模陆ǖ膶ο笠彩遣豢善虻摹?/li>
自旋鎖自旋多少次競爭不到后會(huì)升級到重量級鎖?
- Java6之前:默認(rèn)10次或者cpu核數(shù)的一半
- Java6之后:根據(jù)同一個(gè)線程上次自旋的時(shí)間決定
為什么有了自旋鎖還需要重量級鎖?
自旋是消耗cpu性能的,如果時(shí)間過長或者自旋線程過多,cpu會(huì)被大量消耗重量級鎖中有隊(duì)列waitSet
偏向鎖是否一定比自旋鎖效率高?
- 單線程的時(shí)候偏向鎖效率高
- 多個(gè)線程的時(shí)候偏向鎖會(huì)涉及鎖撤銷,消耗資源,這時(shí)自旋鎖效率高
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧
標(biāo)題名稱:Java并發(fā)編程—鎖升級-創(chuàng)新互聯(lián)
文章網(wǎng)址:http://jinyejixie.com/article36/ccehsg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供關(guān)鍵詞優(yōu)化、建站公司、服務(wù)器托管、標(biāo)簽優(yōu)化、用戶體驗(yàn)、品牌網(wǎng)站制作
廣告
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源:
創(chuàng)新互聯(lián)