synchronized的鎖升級(jí)過(guò)程 :?
鎖的狀態(tài)總共有四種,級(jí)別由低到高依次為:無(wú)鎖喊巍、偏向鎖严衬、輕量級(jí)鎖、重量級(jí)鎖
在?JDK 1.6之前锥涕,synchronized 還是一個(gè)重量級(jí)鎖,是一個(gè)效率比較低下的鎖狭吼,但是在JDK 1.6后层坠,Jvm為了提高鎖的獲取與釋放效率對(duì)(synchronized )進(jìn)行了優(yōu)化,引入了 偏向鎖 和 輕量級(jí)鎖?刁笙,從此以后鎖的狀態(tài)就有了四種(無(wú)鎖破花、偏向鎖、輕量級(jí)鎖疲吸、重量級(jí)鎖)座每,并且四種狀態(tài)會(huì)隨著競(jìng)爭(zhēng)的情況逐漸升級(jí),而且是不可逆的過(guò)程摘悴,即不可降級(jí)峭梳,也就是說(shuō)只能進(jìn)行鎖升級(jí)
synchronized加鎖鎖的對(duì)象就是說(shuō)在對(duì)象頭中修改mark word的信息來(lái)實(shí)現(xiàn)的加鎖,誰(shuí)修改成功誰(shuí)獲得鎖
上圖中,如果對(duì)象最后2bit是00代表輕量級(jí)鎖,如果是10代表重量級(jí)鎖,11代表這個(gè)對(duì)象正在被GC回收,01有二種狀態(tài),再01的前提下,看倒數(shù)第三位0代表無(wú)鎖,1代表是偏向鎖
偏向鎖和輕量級(jí)鎖都是用戶(hù)態(tài)級(jí)別的鎖,不需要經(jīng)過(guò)系統(tǒng)調(diào)用的過(guò)程,所以效率會(huì)高
偏向鎖: 再執(zhí)行的過(guò)程中只有一個(gè)線(xiàn)程執(zhí)行,沒(méi)有發(fā)生鎖的競(jìng)爭(zhēng),直接將線(xiàn)程指針寫(xiě)入到對(duì)象的markeword中
當(dāng)又來(lái)了一個(gè)線(xiàn)程(發(fā)生了競(jìng)爭(zhēng)),會(huì)將偏向鎖撤銷(xiāo),然后進(jìn)行競(jìng)爭(zhēng),每個(gè)線(xiàn)程都有自己的線(xiàn)程棧,每個(gè)人再自己的線(xiàn)程內(nèi)部生成LR(鎖記錄),然后用自旋的方式將自己的lr指針寫(xiě)入到對(duì)象的markeword中,當(dāng)對(duì)象markword中指向了那個(gè)線(xiàn)程的lr,那個(gè)線(xiàn)程爭(zhēng)搶成功,另一個(gè)線(xiàn)程會(huì)繼續(xù)cas的去競(jìng)爭(zhēng),當(dāng)競(jìng)爭(zhēng)成功的線(xiàn)程執(zhí)行完了,這個(gè)線(xiàn)程繼續(xù)執(zhí)行,這個(gè)時(shí)候就是輕量級(jí)鎖
重量級(jí)鎖; 發(fā)生競(jìng)爭(zhēng)但是在自旋過(guò)程中依然沒(méi)有獲取到鎖就會(huì)升級(jí)重量級(jí)鎖,這種鎖? 需要經(jīng)過(guò)一次系統(tǒng)調(diào)用,要上操作系統(tǒng)申請(qǐng)
為什么有自旋還需要重量級(jí)呢? 因?yàn)樽孕切枰腸pu資源的 自旋時(shí)間太長(zhǎng)會(huì)浪費(fèi)cpu資源 重量級(jí)鎖有等待隊(duì)列,將線(xiàn)程放入等待隊(duì)列,不需要消耗cpu資源
自旋幾次呢?? 默認(rèn)是10次(可以設(shè)置)或者自旋線(xiàn)程數(shù)超過(guò)了cpu核數(shù)的一半,但是在jdk1.6進(jìn)行了優(yōu)化,自旋次數(shù)變成了自適應(yīng)的,所以不用去設(shè)置
jvm再啟動(dòng)過(guò)程中,會(huì)有很多線(xiàn)程啟動(dòng),所以jvm剛啟動(dòng)的時(shí)候,偏向鎖不會(huì)打開(kāi),這時(shí)候創(chuàng)建的對(duì)象加鎖會(huì)直接進(jìn)入輕量級(jí)鎖, 默認(rèn)時(shí)間4秒后啟動(dòng) 可以設(shè)置 參數(shù)可以百度一下
剛new的對(duì)象如果偏向鎖沒(méi)有啟動(dòng),就是普通對(duì)象,如果偏向鎖啟動(dòng)就是匿名偏向鎖