從JDK1.6版本之后,synchronized本身也在不斷優(yōu)化鎖的機(jī)制,有些情況下他并不會(huì)是?個(gè)很重量級(jí)的鎖了。優(yōu)化機(jī)制包括?適應(yīng)鎖、?旋鎖、鎖消除、鎖粗化、輕量級(jí)鎖和偏向鎖。
鎖的狀態(tài)從低到?依次為?鎖->偏向鎖->輕量級(jí)鎖->重量級(jí)鎖,升級(jí)的過程就是從低到?,降級(jí)在?定條件也是有可能發(fā)?的。
?旋鎖:由于?部分時(shí)候,鎖被占?的時(shí)間很短,共享變量的鎖定時(shí)間也很短,所有沒有必要掛起線程,?戶態(tài)和內(nèi)核態(tài)的來回上下?切換嚴(yán)重影響性能。?旋的概念就是讓線程執(zhí)??個(gè)忙循環(huán),可以理解為就是啥也不?,防?從?戶態(tài)轉(zhuǎn)?內(nèi)核態(tài),?旋鎖可以通過設(shè)置-XX:+UseSpining來開啟,?旋的默認(rèn)次數(shù)是10次,可以使?-XX:PreBlockSpin設(shè)置。
?適應(yīng)鎖:?適應(yīng)鎖就是?適應(yīng)的?旋鎖,?旋的時(shí)間不是固定時(shí)間,?是由前?次在同?個(gè)鎖上的?旋時(shí)間和鎖的持有者狀態(tài)來決定。
鎖消除:鎖消除指的是JVM檢測(cè)到?些同步的代碼塊,完全不存在數(shù)據(jù)競(jìng)爭(zhēng)的場(chǎng)景,也就是不需要加鎖,就會(huì)進(jìn)?鎖消除。
鎖粗化:鎖粗化指的是有很多操作都是對(duì)同?個(gè)對(duì)象進(jìn)?加鎖,就會(huì)把鎖的同步范圍擴(kuò)展到整個(gè)操作序列之外。
偏向鎖:當(dāng)線程訪問同步塊獲取鎖時(shí),會(huì)在對(duì)象頭和棧幀中的鎖記錄?存儲(chǔ)偏向鎖的線程ID,之后這個(gè)線程再次進(jìn)?同步塊時(shí)都不需要CAS來加鎖和解鎖了,偏向鎖會(huì)永遠(yuǎn)偏向第?個(gè)獲得鎖的線程,如果后續(xù)沒有其他線程獲得過這個(gè)鎖,持有鎖的線程就永遠(yuǎn)不需要進(jìn)?同步,反之,當(dāng)有其他線程競(jìng)爭(zhēng)偏向鎖時(shí),持有偏向鎖的線程就會(huì)釋放偏向鎖??梢?過設(shè)置-XX:+UseBiasedLocking開啟偏向鎖。
輕量級(jí)鎖:JVM的對(duì)象的對(duì)象頭中包含有?些鎖的標(biāo)志位,代碼進(jìn)?同步塊的時(shí)候,JVM將會(huì)使?CAS?
式來嘗試獲取鎖,如果更新成功則會(huì)把對(duì)象頭中的狀態(tài)位標(biāo)記為輕量級(jí)鎖,如果更新失敗,當(dāng)前線程就
嘗試?旋來獲得鎖。
整個(gè)鎖升級(jí)的過程?常復(fù)雜,我盡?去除?些??的環(huán)節(jié),簡(jiǎn)單來描述整個(gè)升級(jí)的機(jī)制。
簡(jiǎn)單點(diǎn)說,偏向鎖就是通過對(duì)象頭的偏向線程ID來對(duì)?,甚?都不需要CAS了,?輕量級(jí)鎖主要就是通
過CAS修改對(duì)象頭鎖記錄和?旋來實(shí)現(xiàn),重量級(jí)鎖則是除了擁有鎖的線程其他全部阻塞。
