synchronized關(guān)鍵字(jvm)實現(xiàn)方式和鎖優(yōu)化

java程序中我們可以使用synchronized關(guān)鍵字對程序加鎖,它可以保證方法或者代碼塊運行時同一時刻只有一個方法可以進入到臨界區(qū)域,同時它還可以保證共享變量的內(nèi)存可見性,synchronzied關(guān)鍵字可以聲明一個同步代碼塊,也可以用來修飾靜態(tài)方法或者實例方法突颊。當(dāng)synchronized修飾在不同地方時裆甩,它也是在對不同對象進行加鎖操作:
1.同步代碼塊:鎖是括號里面的對象
2.靜態(tài)方法:瑣是當(dāng)前類的class對象
3.實例方法:鎖是當(dāng)前實例對象

當(dāng)聲明synchronized代碼塊時冗锁,編譯而成的字節(jié)碼將會包含monitorenter和monitorexit兩個指令,這兩種指令都會消耗操作數(shù)棧上的一個引用類型的元素(代碼塊中小括號里面的對象)作為加鎖和解鎖的對象嗤栓。

  public void foo(Object sync) {
    synchronized (sync) {
      sync.hashCode();
    }
  }
  // 上面的 Java 代碼將編譯為下面的字節(jié)碼
  public void foo(java.lang.Object);
    Code:
       0: aload_1
       1: dup
       2: astore_2
       3: monitorenter
       4: aload_1
       5: invokevirtual java/lang/Object.hashCode:()I
       8: pop
       9: aload_2
      10: monitorexit
      11: goto          19
      14: astore_3
      15: aload_2
      16: monitorexit
      17: aload_3
      18: athrow
      19: return
    Exception table:
       from    to  target type
           4    11    14   any
          14    17    14   any

從上面的字節(jié)碼中可以看到有一個monitorenter指令和多個monitorexit指令冻河,這是因為要確保在任何情況下退出都會釋放掉鎖。關(guān)于monitorenter和monitorexit的作用茉帅,我們可以抽象的理解為每個鎖對象都擁有一個鎖的計數(shù)器和一個持有該鎖的線程指針叨叙。
當(dāng)執(zhí)行到monitorenter時如果鎖計數(shù)器個數(shù)為零則代表沒有其他線程鎖定,這時java虛擬機會將鎖對象的持有線程設(shè)置為當(dāng)前線程堪澎,并把計數(shù)器設(shè)置為1擂错。當(dāng)鎖計數(shù)器不為零時判斷持有鎖對象的線程是不是當(dāng)前線程,如果是當(dāng)前線程則把計數(shù)器加1樱蛤。(因為synchronized是可重入鎖)當(dāng)執(zhí)行到monitorexit時钮呀,jvm會將計數(shù)器個數(shù)減1。當(dāng)計數(shù)器等于零的時候代表鎖已經(jīng)釋放昨凡。

當(dāng)synchronized標(biāo)記方法時爽醋,在字節(jié)碼中flags包括ACC_SYNCHRONIZED。此標(biāo)記標(biāo)識進入該方法時java虛擬機要進行monitorenter操作便脊,在退出時進行(正常退出或者異常退出)monitorexit操作蚂四。


sync.PNG

二 、JAVA對象頭

在java虛擬機中哪痰,每個java對象都有一個對象頭(object header)遂赠,由標(biāo)記字段(Mark Word)和類型指針(Klass Pointer)構(gòu)成。標(biāo)記字段用來存儲對象運行時Java虛擬機有關(guān)該對象的運行數(shù)據(jù)晌杰,如哈希碼解愤、GC信息、鎖狀態(tài)標(biāo)志乎莉、線程持有的鎖等等送讲。類型指針是對象指向它的類元數(shù)據(jù)的指針,Java虛擬機通過該指針確定這個對象是什么類的實例惋啃。

三哼鬓、JVM鎖優(yōu)化

重量級鎖

重量級鎖是java虛擬機中最基本的鎖的實現(xiàn)方式,在這種鎖狀態(tài)下边灭,獲取鎖失敗的線程會進入阻塞狀態(tài)异希,當(dāng)目標(biāo)鎖被釋放時喚醒阻塞線程。
java線程中的阻塞和喚醒都是依靠操作系統(tǒng)來實現(xiàn)的绒瘦,但是這種方式會有系統(tǒng)調(diào)用称簿,需要從操作系統(tǒng)的用戶狀態(tài)切換到內(nèi)核狀態(tài)扣癣,開銷很大。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末憨降,一起剝皮案震驚了整個濱河市父虑,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌授药,老刑警劉巖士嚎,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異悔叽,居然都是意外死亡莱衩,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進店門娇澎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來笨蚁,“玉大人,你說我怎么就攤上這事趟庄∽裕” “怎么了?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵岔激,是天一觀的道長。 經(jīng)常有香客問我是掰,道長虑鼎,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任键痛,我火速辦了婚禮炫彩,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘絮短。我一直安慰自己江兢,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布丁频。 她就那樣靜靜地躺著杉允,像睡著了一般。 火紅的嫁衣襯著肌膚如雪席里。 梳的紋絲不亂的頭發(fā)上叔磷,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天,我揣著相機與錄音奖磁,去河邊找鬼改基。 笑死,一個胖子當(dāng)著我的面吹牛咖为,可吹牛的內(nèi)容都是我干的秕狰。 我是一名探鬼主播稠腊,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼鸣哀!你這毒婦竟也來了架忌?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤诺舔,失蹤者是張志新(化名)和其女友劉穎鳖昌,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體低飒,經(jīng)...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡许昨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了褥赊。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片糕档。...
    茶點故事閱讀 38,814評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖拌喉,靈堂內(nèi)的尸體忽然破棺而出速那,到底是詐尸還是另有隱情,我是刑警寧澤尿背,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布端仰,位于F島的核電站,受9級特大地震影響田藐,放射性物質(zhì)發(fā)生泄漏荔烧。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一汽久、第九天 我趴在偏房一處隱蔽的房頂上張望鹤竭。 院中可真熱鬧,春花似錦景醇、人聲如沸臀稚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽吧寺。三九已至,卻和暖如春散劫,著一層夾襖步出監(jiān)牢的瞬間撮执,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工舷丹, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留抒钱,地道東北人。 一個月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像谋币,于是被迫代替她去往敵國和親仗扬。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,728評論 2 351