Synchronized鎖 偏向鎖 鎖優(yōu)化

  1. Synchronized實現(xiàn)同步
  • 同步普通方法趁窃,鎖當(dāng)前實例對象
  • 同步靜態(tài)方法,鎖當(dāng)前類的Class對象
  • 同步方法塊,鎖是Synchronized()里配置的對象
  1. Synchronized在JVM中的實現(xiàn)原理
    JVM基于進(jìn)入和退出Monitor對象來實現(xiàn)同步。編譯后插入monitorenter到同步代碼塊開始的位置,monitorexit插入到方法結(jié)束處和異常處罐氨。monitor被持有后,進(jìn)入鎖定狀態(tài)滩援,當(dāng)線程執(zhí)行到monitorenter指令時栅隐,將嘗試獲取對象對應(yīng)的monitor所有權(quán),既嘗試獲得對象的鎖玩徊。

synchronized 修飾的方法并沒有 monitorenter 指令和 monitorexit 指令租悄,取得代之的確實是 ACC_SYNCHRONIZED 標(biāo)識,該標(biāo)識指明了該方法是一個同步方法恩袱,JVM 通過該 ACC_SYNCHRONIZED 訪問標(biāo)志來辨別一個方法是否聲明為同步方法泣棋,從而執(zhí)行相應(yīng)的同步調(diào)用。

在 Java 早期版本中畔塔,synchronized 屬于重量級鎖潭辈,效率低下,因為監(jiān)視器鎖(monitor)是依賴于底層的操作系統(tǒng)的 Mutex Lock 來實現(xiàn)的澈吨,Java 的線程是映射到操作系統(tǒng)的原生線程之上的把敢。如果要掛起或者喚醒一個線程,都需要操作系統(tǒng)幫忙完成谅辣,而操作系統(tǒng)實現(xiàn)線程之間的切換時需要從用戶態(tài)轉(zhuǎn)換到內(nèi)核態(tài)技竟,這個狀態(tài)之間的轉(zhuǎn)換需要相對比較長的時間,時間成本相對較高屈藐,這也是為什么早期的 synchronized 效率低的原因。慶幸的是在 Java 6 之后 Java 官方對從 JVM 層面對synchronized 較大優(yōu)化熙尉,所以現(xiàn)在的 synchronized 鎖效率也優(yōu)化得很不錯了联逻。JDK1.6對鎖的實現(xiàn)引入了大量的優(yōu)化,如自旋鎖检痰、適應(yīng)性自旋鎖包归、鎖消除、鎖粗化铅歼、偏向鎖公壤、輕量級鎖等技術(shù)來減少鎖操作的開銷。[1]

  1. Java對象頭
    存儲兩部分信息
  • 對象自身的運(yùn)行時數(shù)據(jù)椎椰,
    • HashCode
    • GC分代年齡
    • 鎖狀態(tài)標(biāo)志
    • 是否偏向鎖標(biāo)記位
    • 偏向線程ID

這部分?jǐn)?shù)據(jù)的長度在32位和64位的虛擬機(jī)中分別為32bit和64bit厦幅,也叫做Mark Word】考慮到虛擬機(jī)的空間效率确憨,Mark Word被設(shè)計成一個非固定的數(shù)據(jù)結(jié)構(gòu)以便在極小的空間內(nèi)存儲盡量多的信息译荞。根據(jù)鎖狀態(tài)的不同存儲的信息也不同,見下圖所示:


在這里插入圖片描述

在32位的HotSpot虛擬機(jī)中休弃,對象未被鎖定的狀態(tài)下吞歼,Mark Word的32bit空間中的25bit用于存儲對象HashCode,4bit用于存儲對象分代年齡塔猾,2bit用于存儲鎖標(biāo)志位篙骡,1bit固定為0。
上圖也展示了在其他狀態(tài)下(輕量級鎖定丈甸、重量級鎖定糯俗、GC標(biāo)記、可偏向)下對象的存儲內(nèi)容老虫。

  • 存儲指向方法區(qū)對象類型數(shù)據(jù)的指針叶骨,如果是數(shù)組對象的話,還會有一個額外的部分用于存儲數(shù)組長度祈匙。

重量級鎖叫重量級的原因忽刽,是因為在多線程競爭下,需要操作系統(tǒng)互斥量mutex夺欲,這種同步方式的成本非常高跪帝,包括系統(tǒng)調(diào)用引起的內(nèi)核態(tài)與用戶態(tài)切換線程阻塞造成的線程切換等些阅。因此伞剑,后來稱這種鎖為“重量級鎖”。

  1. 鎖的升級
    鎖有四種狀態(tài)市埋,從低到高依次是:無鎖狀態(tài)黎泣、偏向鎖狀態(tài)、輕量級鎖狀態(tài)和重量級鎖狀態(tài)缤谎。鎖可以升級不能降級抒倚。
  • 輕量級鎖
    • 在代碼進(jìn)入同步塊時,如果同步對象沒有被鎖定坷澡,即Mark word處于無鎖狀態(tài)(鎖標(biāo)志位為“01”狀態(tài)托呕,是否為偏向鎖為“0”),虛擬機(jī)將在當(dāng)前線程的棧幀中建立一個名為鎖記錄(Lock Record)的空間频敛,用于存儲鎖對象目前的Mark Word的拷貝项郊,官方把這個拷貝加了一個Displaced前綴,即Displaced Mark Word斟赚,這時候線程堆棧與對象頭的狀態(tài)如下圖所示


      在這里插入圖片描述
  • 使用CSA操作將對象的Mark Word更新為指向Lock Record的指針着降,如果這個更新動作成功了,那么這個線程就擁有了該對象的鎖拗军。對象Mark Down的鎖標(biāo)志位(Mark Word的最后2bit)轉(zhuǎn)變成"00"鹊碍,這時候線程堆棧與對象頭的狀態(tài)如下所示:


    在這里插入圖片描述
  • 如果更新操作失敗了厌殉,==虛擬機(jī)首先會檢查對象的Mark Word是否指向當(dāng)前線程的棧幀==。否則說明這個對象鎖已經(jīng)被其他線程占用了侈咕,這時候自旋等待公罕,如果還是沒有拿到鎖,輕量級鎖膨脹為重量級鎖耀销,鎖標(biāo)志的狀態(tài)值變?yōu)椤?0”楼眷,Mark Word中存儲的就是指向重量級鎖(互斥量)的指針,后面等待鎖的線程也要進(jìn)入阻塞狀態(tài)熊尉。

這里我的理解是這樣的罐柳,如果線程要獲取的對象鎖是處于無鎖狀態(tài),那么到這一步更新操作失敗了狰住,已經(jīng)能夠說明是有別的線程在一起競爭张吉,這里的檢查Mark Word肯定是會指向別的線程的,不知道為什么書中和網(wǎng)上的資料都說第一步會檢查是否指向當(dāng)前線程催植。原因可能是如果當(dāng)前線程要獲取的對象鎖不是無鎖狀態(tài)肮蛹,而是處于偏向鎖狀態(tài)了,那么第一步肯定是檢查Mark Word是否指向了自己線程的棧幀创南,如果是伦忠,說明當(dāng)前線程已經(jīng)擁有了這個鎖了,直接進(jìn)入同步塊執(zhí)行稿辙。

Java Synchronized原理圖見下圖[2]

在這里插入圖片描述

所有的鎖見下圖[3]

[圖片上傳失敗...(image-484f37-1551705563425)]


  1. https://github.com/Snailclimb/JavaGuide/blob/master/Java%E7%9B%B8%E5%85%B3/synchronized.md ?

  2. https://ccqy66.github.io/2018/03/07/java%E9%94%81%E5%81%8F%E5%90%91%E9%94%81/ ?

  3. https://segmentfault.com/a/1190000017037430 ?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末昆码,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子邻储,更是在濱河造成了極大的恐慌赋咽,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,865評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吨娜,死亡現(xiàn)場離奇詭異脓匿,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)萌壳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,296評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來日月,“玉大人袱瓮,你說我怎么就攤上這事“В” “怎么了尺借?”我有些...
    開封第一講書人閱讀 169,631評論 0 364
  • 文/不壞的土叔 我叫張陵,是天一觀的道長精拟。 經(jīng)常有香客問我燎斩,道長虱歪,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,199評論 1 300
  • 正文 為了忘掉前任栅表,我火速辦了婚禮笋鄙,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘怪瓶。我一直安慰自己萧落,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 69,196評論 6 398
  • 文/花漫 我一把揭開白布洗贰。 她就那樣靜靜地躺著找岖,像睡著了一般。 火紅的嫁衣襯著肌膚如雪敛滋。 梳的紋絲不亂的頭發(fā)上许布,一...
    開封第一講書人閱讀 52,793評論 1 314
  • 那天,我揣著相機(jī)與錄音绎晃,去河邊找鬼蜜唾。 笑死,一個胖子當(dāng)著我的面吹牛箕昭,可吹牛的內(nèi)容都是我干的灵妨。 我是一名探鬼主播,決...
    沈念sama閱讀 41,221評論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼落竹,長吁一口氣:“原來是場噩夢啊……” “哼泌霍!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起述召,我...
    開封第一講書人閱讀 40,174評論 0 277
  • 序言:老撾萬榮一對情侶失蹤朱转,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后积暖,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體藤为,經(jīng)...
    沈念sama閱讀 46,699評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,770評論 3 343
  • 正文 我和宋清朗相戀三年夺刑,在試婚紗的時候發(fā)現(xiàn)自己被綠了缅疟。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,918評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡遍愿,死狀恐怖存淫,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情沼填,我是刑警寧澤桅咆,帶...
    沈念sama閱讀 36,573評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站坞笙,受9級特大地震影響岩饼,放射性物質(zhì)發(fā)生泄漏荚虚。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,255評論 3 336
  • 文/蒙蒙 一籍茧、第九天 我趴在偏房一處隱蔽的房頂上張望版述。 院中可真熱鬧,春花似錦硕糊、人聲如沸院水。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,749評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽檬某。三九已至,卻和暖如春螟蝙,著一層夾襖步出監(jiān)牢的瞬間恢恼,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,862評論 1 274
  • 我被黑心中介騙來泰國打工胰默, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留场斑,地道東北人。 一個月前我還...
    沈念sama閱讀 49,364評論 3 379
  • 正文 我出身青樓牵署,卻偏偏與公主長得像漏隐,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子奴迅,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,926評論 2 361

推薦閱讀更多精彩內(nèi)容