Java鎖的升級(jí)策略 偏向鎖 輕量級(jí)鎖 重量級(jí)鎖
這三種鎖是指鎖的狀態(tài),并且是專門針對(duì)Synchronized關(guān)鍵字。JDK 1.6 為了減少"重量級(jí)鎖"的性能消耗,引入了“偏向鎖”和“輕量級(jí)鎖”,鎖一共擁有4種狀態(tài):無鎖狀態(tài)、偏向鎖、輕量級(jí)鎖、重量級(jí)鎖。鎖狀態(tài)是通過對(duì)象頭的Mark Word來進(jìn)行標(biāo)記的:

鎖可以升級(jí)但不能降級(jí),意味著偏向鎖升級(jí)成輕量級(jí)鎖后不能降級(jí)成偏向鎖,這種鎖升級(jí)卻不能降級(jí)的策略,是為了提高獲得鎖和釋放鎖的效率
重量級(jí)鎖:依賴于底層操作系統(tǒng)的Mutex Lock,線程會(huì)被阻塞住
缺點(diǎn):加鎖和解鎖需要從用戶態(tài)切換到內(nèi)核態(tài),性能消耗較大
輕量級(jí)鎖:基于重量級(jí)鎖進(jìn)行了優(yōu)化(避免上下文切換,提高了性能),它假設(shè)多線程競(jìng)爭(zhēng)是互相錯(cuò)開的,不會(huì)發(fā)生線程阻塞,呢么上下文切換就是多余的
第一個(gè)特點(diǎn):采用了CAS操作加鎖和解鎖,由于輕量級(jí)鎖的鎖記錄(Lock Record)是存放在對(duì)象頭和線程空間里的,因此加鎖和解鎖不需要上下文切換,性能消耗較小
第二個(gè)特點(diǎn):一旦發(fā)生多線程競(jìng)爭(zhēng),首先基于“自旋鎖”思想,自旋CPU循環(huán)等待一段時(shí)間,不會(huì)發(fā)生上下文切換,如果還是無法獲得鎖,就將鎖升級(jí)為重量級(jí)鎖
偏向鎖:基于輕量級(jí)鎖進(jìn)行了優(yōu)化(減少多次的加鎖和解鎖,提高了性能),它假設(shè)整個(gè)過程只有一個(gè)線程獲得鎖,呢么多次的加鎖和解鎖就是多余的
特點(diǎn):在第一次獲得鎖之后不會(huì)釋放鎖,它會(huì)一直持有鎖,后續(xù)進(jìn)入鎖時(shí)只需檢查一下鎖狀態(tài)和偏向線程ID是否為自己,從而省去了多次的加鎖和解鎖
1.偏向鎖
獲取鎖:
檢測(cè)對(duì)象頭的Mark Word是否為可偏向狀態(tài)(即是否為偏向鎖1,鎖標(biāo)志位是否為01),如果不是,嘗試競(jìng)爭(zhēng)鎖:嘗試CAS操作將Mark Word的線程ID設(shè)置為當(dāng)前線程ID,以表示線程獲得鎖,如果失敗說明鎖已被占用
若為可偏向狀態(tài),則檢查線程ID是否為當(dāng)前線程ID,如果是則表示當(dāng)前線程已經(jīng)持有鎖(鎖的可重入),否則說明鎖已被占用
如果鎖已被占用,只能撤銷偏向鎖為無鎖狀態(tài)或輕量級(jí)鎖
釋放鎖:(偏向鎖使用了一種等到競(jìng)爭(zhēng)出現(xiàn)才釋放鎖的機(jī)制,線程是不會(huì)主動(dòng)釋放偏向鎖的,只有當(dāng)其他線程競(jìng)爭(zhēng)偏向鎖時(shí),持有偏向鎖的線程才會(huì)釋放鎖)
偏向鎖的撤銷需要等待全局安全點(diǎn)(在這個(gè)時(shí)間點(diǎn)沒有正在執(zhí)行的字節(jié)碼),暫停擁有偏向鎖的線程,檢查持有偏向鎖的線程是否還活著
如果線程掛了,則將對(duì)象頭設(shè)置成無鎖狀態(tài);如果線程仍然活著,則將對(duì)象頭設(shè)置為輕量級(jí)鎖(鎖的升級(jí)),最終輕量級(jí)鎖一定會(huì)被釋放
2.輕量級(jí)鎖
獲取鎖:
檢測(cè)對(duì)象頭的Mark Word是否為輕量級(jí)鎖(鎖標(biāo)志位為00),如果不是,嘗試競(jìng)爭(zhēng)鎖:JVM首先在當(dāng)前線程的棧幀中建立一個(gè)鎖記錄(Lock Record),用于備份存儲(chǔ)對(duì)象頭的Mark Word(官方把這份拷貝加了一個(gè)Displaced前綴,稱為Displaced Mark Word),然后JVM嘗試CAS操作將Mark Word更新為指向Lock Record的指針,以表示線程獲得鎖,如果失敗說明鎖已被占用
若為輕量級(jí)鎖,判斷對(duì)象頭的Mark Word是否指向當(dāng)前線程的棧幀的Lock Record,如果是則表示當(dāng)前線程已經(jīng)持有鎖(鎖的可重入),否則說明鎖已被占用
如果鎖已被占用,當(dāng)前線程便嘗試自旋CPU來獲取鎖,自旋一定次數(shù)后輕量級(jí)鎖會(huì)膨脹為重量級(jí)鎖(鎖標(biāo)志位變成10),線程進(jìn)入阻塞
釋放鎖:
嘗試CAS操作將Displaced Mark Word中替換回對(duì)象頭,如果成功,說明輕量級(jí)鎖釋放成功
如果CAS操作失敗,說明存在鎖競(jìng)爭(zhēng),鎖已經(jīng)膨脹成重量級(jí)鎖,需要在釋放鎖的同時(shí)喚醒那些被掛起的線程
3.重量級(jí)鎖
重量級(jí)鎖依賴于底層操作系統(tǒng)的Mutex Lock,所有線程都會(huì)被阻塞住,線程之間的切換需要從用戶態(tài)到內(nèi)核態(tài),切換成本非常高。
總結(jié):鎖的優(yōu)缺點(diǎn)對(duì)比
| 鎖 | 優(yōu)點(diǎn) | 缺點(diǎn) | 適用場(chǎng)景 |
|---|---|---|---|
| 偏向鎖(Biased Lock) | 加鎖和解鎖不需要額外的消耗,和執(zhí)行非同步方法相比僅存在納秒級(jí)的差距 | 如果線程間存在鎖競(jìng)爭(zhēng),會(huì)帶來額外的鎖撤銷 | 適用于只有一個(gè)線程訪問 |
| 輕量級(jí)鎖(Lightweight Lock) | 競(jìng)爭(zhēng)的線程不會(huì)阻塞,提高了程序的響應(yīng)速度 | 對(duì)于得不到鎖的線程,自旋會(huì)消耗CPU | 追求響應(yīng)時(shí)間,或者要求臨界區(qū)簡(jiǎn)短,自旋不會(huì)占用CPU過久 |
| 重量級(jí)鎖(Heavyweight Lock) | 線程競(jìng)爭(zhēng)不使用自旋,不會(huì)消耗CPU資源 | 線程阻塞,響應(yīng)時(shí)間緩慢 | 追求吞吐量 |
相關(guān)文章
阿里面試Nacos配置中心交互模型是push還是pull原理解析
這篇文章主要為大家介紹了阿里面試Nacos配置中心交互模型是push還是pull原理解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07
Java技術(shù)長(zhǎng)久占居主要地位的12個(gè)原因
這篇文章主要為大家詳細(xì)介紹了12個(gè)Java長(zhǎng)久占居主要地位的原因,感興趣的小伙伴們可以參考一下2016-07-07
SpringCloud Zuul過濾器實(shí)現(xiàn)登陸鑒權(quán)代碼實(shí)例
這篇文章主要介紹了SpringCloud Zuul過濾器實(shí)現(xiàn)登陸鑒權(quán)代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03
解決@CachePut設(shè)置的key值無法與@CacheValue的值匹配問題
這篇文章主要介紹了解決@CachePut設(shè)置的key的值無法與@CacheValue的值匹配問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12
SpringBoot整合之SpringBoot整合MongoDB的詳細(xì)步驟
這篇文章主要介紹了SpringBoot整合之SpringBoot整合MongoDB的詳細(xì)步驟,本文通過圖文實(shí)例代碼相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-07-07
IDEA創(chuàng)建web項(xiàng)目出現(xiàn)404錯(cuò)誤解決方法
今天先來搭建一個(gè)web工程,工程搭建好運(yùn)行時(shí)發(fā)現(xiàn)404,本文主要介紹了IDEA創(chuàng)建web項(xiàng)目出現(xiàn)404錯(cuò)誤解決方法,具有一定的參考價(jià)值,感興趣的可以了解一下2023-09-09
SpringBoot詳細(xì)講解異步任務(wù)如何獲取HttpServletRequest
在使用框架日常開發(fā)中需要在controller中進(jìn)行一些異步操作減少請(qǐng)求時(shí)間,但是發(fā)現(xiàn)在使用@Anysc注解后會(huì)出現(xiàn)Request對(duì)象無法獲取的情況,本文就此情況給出完整的解決方案2022-04-04
ShardingSphere數(shù)據(jù)分片算法及測(cè)試實(shí)戰(zhàn)
這篇文章主要為大家介紹了ShardingSphere數(shù)據(jù)分片算法及測(cè)試實(shí)戰(zhàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03

