JDK版本: 1.6
前言
jdk1.6對(duì)synchronized鎖進(jìn)行了一些列的優(yōu)化, 由原來(lái)的直接使用重量級(jí)鎖,改為鎖強(qiáng)度逐漸升級(jí)的方式,主要分為三種強(qiáng)度的鎖,無(wú)鎖>偏向鎖>輕量級(jí)鎖>重量級(jí)鎖,且只能升級(jí)不能降級(jí). 期間使用了CAS和自旋,自適應(yīng)自旋,鎖粗化,鎖消除等技術(shù)
基本概念
自旋鎖
根據(jù)經(jīng)驗(yàn), 線(xiàn)程自旋等待一會(huì), 不放棄CPU執(zhí)行時(shí)間, 通惩保可以取得很好的效果, 一般都能拿到鎖
自適應(yīng)自旋
根據(jù)上次自旋的效果, 如果上次獲取鎖成功, 那么本次自旋的次數(shù)會(huì)增加, 如果之前是失敗的, 那么自旋次數(shù)會(huì)一直減少直到減少到0,避免浪費(fèi)處理器資源
鎖消除
StringBuffer的append方法如果在一個(gè)方法塊中運(yùn)行, 虛擬機(jī)檢測(cè)到方法不會(huì)逃逸出去, 那么就會(huì)進(jìn)行鎖消除
鎖粗化
單線(xiàn)程一個(gè)代碼塊中如果頻繁的加鎖和釋放鎖, 對(duì)性能會(huì)有影響, 于是通過(guò)鎖粗化, 在開(kāi)始和結(jié)束的時(shí)候進(jìn)行加鎖和釋放即可
無(wú)鎖
鎖資源未被任何線(xiàn)程持有
偏向鎖
大多數(shù)情況下, 鎖不存在多線(xiàn)程競(jìng)爭(zhēng)的情況, 都是單個(gè)線(xiàn)程持有,為了避免頻繁使用CAS更新對(duì)象頭部的MarkWord,于是引入了偏向鎖, 線(xiàn)程只需要判斷對(duì)象頭部的線(xiàn)程Id是否為當(dāng)前線(xiàn)程,如果是,即可獲取到鎖資源
輕量級(jí)鎖
輕量級(jí)鎖的引入,處于一種假設(shè),假設(shè)多線(xiàn)程競(jìng)爭(zhēng)鎖資源的情況下,線(xiàn)程可以通過(guò)自旋一段時(shí)間,即可獲取到鎖資源.
這樣的好處是申請(qǐng)鎖的線(xiàn)程不必放棄CPU使用時(shí)間,降低線(xiàn)程上下文切換所造成的開(kāi)銷(xiāo)
重量級(jí)鎖
直接阻塞等待鎖資源的線(xiàn)程,通過(guò)操作系統(tǒng)mutex機(jī)制,鎖定資源,涉及到內(nèi)核線(xiàn)程和用戶(hù)線(xiàn)程的切換,開(kāi)銷(xiāo)相對(duì)較大
鎖升級(jí)過(guò)程
無(wú)鎖>偏向鎖
需要注意的是,偏向鎖的撤銷(xiāo),是被動(dòng)的,只有其他線(xiàn)程嘗試獲取偏向鎖,才會(huì)去撤銷(xiāo)當(dāng)前線(xiàn)程所持有的偏向鎖,然后根據(jù)當(dāng)前線(xiàn)程的方法執(zhí)行情況,設(shè)置對(duì)象頭中的鎖狀態(tài)為無(wú)鎖狀態(tài)或者升級(jí)為偏向鎖
偏向鎖>輕量級(jí)鎖
- 線(xiàn)程2來(lái)競(jìng)爭(zhēng)鎖對(duì)象;
- 判斷當(dāng)前對(duì)象頭是否是偏向鎖;
- 判斷擁有偏向鎖的線(xiàn)程1是否還存在;
- 線(xiàn)程1不存在,直接設(shè)置偏向鎖標(biāo)識(shí)為0(線(xiàn)程1執(zhí)行完畢后,不會(huì)主動(dòng)去釋放偏向鎖);
- 使用cas替換偏向鎖線(xiàn)程ID為線(xiàn)程2,鎖不升級(jí)贡未,仍為偏向鎖;
- 線(xiàn)程1仍然存在,暫停線(xiàn)程1怕犁;
- 設(shè)置鎖標(biāo)志位為00(變?yōu)檩p量級(jí)鎖),偏向鎖為0;
- 從線(xiàn)程1的空閑monitor record中讀取一條,放至線(xiàn)程1的當(dāng)前monitor record中;
- 更新mark word,將mark word指向線(xiàn)程1中monitor record的指針;
- 繼續(xù)執(zhí)行線(xiàn)程1的代碼;
- 鎖升級(jí)為輕量級(jí)鎖;
- 線(xiàn)程2自旋來(lái)獲取鎖對(duì)象;
輕量級(jí)鎖>重量級(jí)鎖
鎖升級(jí)全過(guò)程
首先看下內(nèi)存中和synchronized鎖相關(guān)的數(shù)據(jù)結(jié)構(gòu),主要包括:線(xiàn)程,方法棧,對(duì)象頭部,MonitorObject四個(gè)對(duì)象
?
- 對(duì)象頭信息被稱(chēng)為mark word,保存了鎖相關(guān)的信息
- MonitorObject用于實(shí)現(xiàn)重量級(jí)鎖, 底層通過(guò)操作系統(tǒng)的mutex來(lái)阻塞獲取鎖資源的線(xiàn)程
主要過(guò)程
1.初始狀態(tài)為無(wú)鎖狀態(tài)
2.線(xiàn)程1判斷java對(duì)象頭部中的線(xiàn)程Id是否為當(dāng)前線(xiàn)程
如果是: 則獲取鎖成功, 執(zhí)行步驟13
如果不是: 則CAS修改**對(duì)象頭部**的中的線(xiàn)程Id為**線(xiàn)程1**的線(xiàn)程Id,獲取偏向鎖成功
3.線(xiàn)程1繼續(xù)執(zhí)行
4.線(xiàn)程2嘗試獲取鎖,發(fā)現(xiàn)對(duì)象頭部中的線(xiàn)程Id不是線(xiàn)程2的線(xiàn)程Id,于是CAS嘗試修改對(duì)象頭部線(xiàn)程Id,由于此時(shí)頭部中的線(xiàn)程Id不為null, 修改失敗
5.執(zhí)行撤銷(xiāo)線(xiàn)程1偏向鎖操作
6.stop the world
7.檢查線(xiàn)程1的棧幀列表中是否存在該鎖信息,用于判斷被加鎖的方法是否正在運(yùn)行
如果沒(méi)有運(yùn)行,則鎖狀態(tài)被設(shè)置為**無(wú)鎖轉(zhuǎn)態(tài)**,**線(xiàn)程2**使用CAS獲取偏向鎖成功,執(zhí)行步驟13
如果正在運(yùn)行,即鎖定的代碼塊正在**方法棧列表**中執(zhí)行, 那么鎖升級(jí)為輕量級(jí)鎖,此時(shí)方法棧中會(huì)生成LockRecord信息,并使用CAS替換對(duì)象頭的MarkWord信息
8.線(xiàn)程1被喚醒繼續(xù)運(yùn)行
9.線(xiàn)程2通過(guò)CAS自旋嘗試獲取輕量鎖
**線(xiàn)程1**執(zhí)行完畢,釋放輕量級(jí)鎖, 于是**線(xiàn)程2**獲取輕量級(jí)鎖成功,執(zhí)行步驟13
**線(xiàn)程1**還在執(zhí)行,則**線(xiàn)程2**獲取鎖失敗,鎖膨脹,升級(jí)為**重量級(jí)鎖**,**線(xiàn)程2**阻塞
10.線(xiàn)程1繼續(xù)執(zhí)行
11.線(xiàn)程1執(zhí)行完畢后,釋放鎖,并喚醒阻塞中的線(xiàn)程,此時(shí)線(xiàn)程2被喚醒
12.此時(shí)如果只剩下線(xiàn)程2嘗試去獲取鎖資源,那么線(xiàn)程2獲取重量級(jí)鎖成功,執(zhí)行步驟13
13.成功返回
鎖的優(yōu)缺點(diǎn)比較
圖片來(lái)自書(shū)籍: java并發(fā)編程的藝術(shù)
結(jié)語(yǔ)
對(duì)于鎖升級(jí)全過(guò)程這部分的內(nèi)容, 大家有任何想法,歡迎評(píng)論區(qū)留言~
參考資料
書(shū)籍:java并發(fā)編程的藝術(shù)
ObjectMonitor數(shù)據(jù)結(jié)構(gòu): http://www.sohu.com/a/328600103_120210224>
ObjectMonitor英文資料: https://www.artima.com/insidejvm/ed2/threadsynchP.html
Object類(lèi)中的wait和notify方法: https://blog.csdn.net/qq_38293564/article/details/80432875
https://blog.csdn.net/qq_38293564/article/details/80409861
https://blog.csdn.net/u012465296/article/details/53022317
https://www.cnblogs.com/javaminer/p/3889023.html
https://blog.csdn.net/tongdanping/article/details/79647337
https://blog.csdn.net/zqz_zqz/article/details/70233767
https://www.cnblogs.com/paddix/p/5405678.html
http://www.reibang.com/p/5da9ef598604
http://www.voidcn.com/article/p-hagongck-wk.html
https://juejin.im/post/5abc9de851882555770c8c72
https://blog.csdn.net/wojiao228925661/article/details/100145157