高并發(fā)編程-鎖優(yōu)化

Java在語言上支持了鎖的特性袒餐,在很多常用類的實現(xiàn)中也使用了鎖础废,對于Java開發(fā)者來說就可以很方便的使用這些鎖及常用類篡诽。但是,隨著鎖的頻繁使用及錯用席镀,隨之而來的就是程序執(zhí)行效率變低匹中、應(yīng)用變的緩慢。為了提高線程對共享數(shù)據(jù)訪問的效率豪诲,HotSpot虛擬機(jī)從JDK1.5到JDK1.6做了重大改進(jìn)顶捷,提供了很多鎖優(yōu)化技術(shù),包括自旋鎖屎篱、自適應(yīng)自旋鎖服赎、鎖消除、鎖粗化交播、輕量級鎖和偏向鎖重虑。

自旋鎖

線程的執(zhí)行是通過競爭獲取處理器的執(zhí)行時間才執(zhí)行的。當(dāng)線程掛起或恢復(fù)執(zhí)行的時秦士,會從用戶態(tài)轉(zhuǎn)入內(nèi)核態(tài)中完成缺厉,這種操作是很消耗時間的,在并發(fā)情況下對應(yīng)用和系統(tǒng)來說都有很大壓力。HotSpot虛擬機(jī)的開發(fā)人員注意到很多應(yīng)用對共享數(shù)據(jù)鎖定的時間都是很短暫的提针,為了這短暫的時間而掛起和恢復(fù)線程是不值得的命爬。所以,線程并發(fā)請求鎖的時候辐脖,讓后來的線程在不放棄處理器執(zhí)行時間的情況下稍等一下遇骑,線程做自旋,自旋期間觀察持有鎖的線程是否會很快釋放鎖揖曾,這種技術(shù)就是所謂的自旋鎖。

自旋鎖在JDK1.6中是默認(rèn)開啟的亥啦,默認(rèn)自旋次數(shù)是10次炭剪,可以使用參數(shù)-XX:PreBlockSpin修改默認(rèn)值。雖然翔脱,自旋鎖避免了線程掛起和恢復(fù)的開銷奴拦,但是它占用了處理器的執(zhí)行時間,如果鎖占用時間很短届吁,自旋鎖效果很好错妖,否則會浪費處理器的執(zhí)行時間,影響應(yīng)用的整體性能疚沐。

自適應(yīng)自旋鎖

在JDK1.6中引入了自適應(yīng)自旋鎖暂氯,自旋的次數(shù)由上一次在同一個鎖上自旋的時間和鎖持有者的狀態(tài)來決定。如果上一次同一個鎖通過自旋剛剛被獲取亮蛔,并且持有鎖的線程正在運行痴施,那么虛擬機(jī)認(rèn)為本次自旋也會成功,將會自旋相對長的時間獲取鎖究流。如果同一個鎖很少通過自旋成功被獲取辣吃,那么虛擬機(jī)認(rèn)為本次自旋也會失敗,不會執(zhí)行自旋操作芬探。

鎖消除

一些使用了鎖控制的代碼神得,在虛擬機(jī)即時編譯器運行時檢測到不存在對共享數(shù)據(jù)的競爭訪問,也就是代碼只會被一個線程訪問偷仿,此時會對鎖進(jìn)行消除哩簿,這項優(yōu)化稱為鎖消除。鎖消除的主要判斷依據(jù)來源于逃逸分析(即分析對象的動態(tài)作用域炎疆,一個對象在方法內(nèi)被定義后卡骂,在別的方法或線程中無法通過任何途徑訪問到這個對象,則可以進(jìn)行一些優(yōu)化操作)的數(shù)據(jù)支持形入。

鎖粗化

大多數(shù)情況下全跨,為了提高程序的執(zhí)行效率,會縮小鎖作用的范圍亿遂。但是浓若,對于一些連續(xù)操作都對同一個對象進(jìn)行反復(fù)加鎖渺杉、釋放鎖的情況來說,縮小鎖的作用范圍會消耗更多的資源挪钓,這種情況需要擴(kuò)大鎖的作用范圍是越,這項優(yōu)化稱為鎖粗化。

輕量級鎖

了解輕量級鎖之前碌上,先了解一下Java對象在內(nèi)存中存儲的數(shù)據(jù)結(jié)構(gòu)倚评。在HotSpot虛擬機(jī)中,Java對象在內(nèi)存中存儲的布局分為3塊區(qū)域:對象頭馏予、實例數(shù)據(jù)和對齊填充天梧。對象頭包含兩部分,第一部分包含對象的HashCode霞丧、分代年齡呢岗、鎖標(biāo)志位、線程持有的鎖蛹尝、偏向線程ID等數(shù)據(jù)后豫,這部分?jǐn)?shù)據(jù)的長度在32位和64位虛擬機(jī)中分別為32bit和64bit,官方稱為Mark World突那〈炷穑考慮到虛擬機(jī)的空間效率,Mark World內(nèi)部的數(shù)據(jù)結(jié)構(gòu)是非固定的陨收,也就是說對象頭中存儲的內(nèi)容是不固定的饭豹,下圖展示了不同狀態(tài)下,對象頭中存儲的內(nèi)容:

Mark-World (1).png

當(dāng)代碼執(zhí)行到同步代碼時务漩,如果此時對象的鎖未被鎖定(鎖標(biāo)志位位01)拄衰,虛擬機(jī)將在當(dāng)前線程的棧幀中創(chuàng)建一個名為Lock Record空間,這個空間用于存儲當(dāng)前對象的Mark World拷貝饵骨,具體如下圖所示翘悉。

lock-record-1.png

接著,虛擬機(jī)使用CAS嘗試將對象的對象頭Mark Wolrd指向Lock Record居触,也就是在Mark Wolrd的30bit存儲Lock Record的起始地址妖混,具體如下圖所示。如果上述操作執(zhí)行成功轮洋,當(dāng)前線程就持有了對象的鎖制市,此時對象處于輕量級鎖鎖定狀態(tài),對應(yīng)的鎖標(biāo)志位為00弊予。

lock-record-2.png

如果上述操作執(zhí)行失敗祥楣,首先會檢查對象的對象頭Mark World是否指向了當(dāng)前線程棧幀中的Lock Record,如果指向了則表示當(dāng)前線程已經(jīng)持有了對象的鎖,否則表示對象的鎖已經(jīng)被其它線程持有误褪,鎖膨脹為重量級鎖责鳍,線程掛起等待。

輕量級鎖的釋放過程兽间,通過CAS將Lock Record中存儲的Mark Wolrd拷貝替換回對象的對象頭Mark Wolrd中历葛,替換成功則鎖釋放成功,否則表示有其它線程嘗試獲取過鎖嘀略,釋放鎖的同時恤溶,喚醒掛起的線程,這里筆者的理解是此時鎖膨脹為重量級鎖帜羊,喚醒等待線程競爭宏娄。

偏向鎖

鎖對象第一次被線程持有的時候,虛擬機(jī)通過CAS把獲取到這個鎖的線程ID記錄到對象頭Mark World中逮壁,操作成功則成功獲取偏向鎖,對象頭中的鎖標(biāo)志位設(shè)置為01粮宛。持有偏向鎖的線程每次執(zhí)行到這段同步代碼時窥淆,不需要任何同步操作,這項優(yōu)化稱為偏向鎖巍杈。

當(dāng)有其它線程嘗試獲取對象的鎖時忧饭,終止偏向模式,同時根據(jù)鎖是否處于鎖定狀態(tài)筷畦,撤銷偏向鎖恢復(fù)到未鎖定或輕量級鎖狀態(tài)词裤。

END

如果覺得有收獲,記得關(guān)注鳖宾、點贊吼砂、轉(zhuǎn)發(fā)。

image
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末鼎文,一起剝皮案震驚了整個濱河市渔肩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌拇惋,老刑警劉巖周偎,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異撑帖,居然都是意外死亡蓉坎,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進(jìn)店門胡嘿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蛉艾,“玉大人,你說我怎么就攤上這事∷磐ǎ” “怎么了箍土?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長罐监。 經(jīng)常有香客問我吴藻,道長,這世上最難降的妖魔是什么弓柱? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任沟堡,我火速辦了婚禮,結(jié)果婚禮上矢空,老公的妹妹穿的比我還像新娘航罗。我一直安慰自己,他們只是感情好屁药,可當(dāng)我...
    茶點故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布粥血。 她就那樣靜靜地躺著,像睡著了一般酿箭。 火紅的嫁衣襯著肌膚如雪复亏。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天缭嫡,我揣著相機(jī)與錄音缔御,去河邊找鬼。 笑死妇蛀,一個胖子當(dāng)著我的面吹牛耕突,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播评架,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼眷茁,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了纵诞?” 一聲冷哼從身側(cè)響起蔼卡,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎挣磨,沒想到半個月后雇逞,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡茁裙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年塘砸,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片晤锥。...
    茶點故事閱讀 38,577評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡掉蔬,死狀恐怖廊宪,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情女轿,我是刑警寧澤箭启,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站蛉迹,受9級特大地震影響傅寡,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜北救,卻給世界環(huán)境...
    茶點故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一荐操、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧珍策,春花似錦托启、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蹭劈,卻和暖如春肩民,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背链方。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留灶搜,地道東北人祟蚀。 一個月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像割卖,于是被迫代替她去往敵國和親前酿。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,452評論 2 348

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

  • AIDL簡介 AIDL是對以 Binder 為核心的跨進(jìn)程通信機(jī)制的進(jìn)一步封裝鹏溯,使得這個過程更加簡化罢维,只暴露出非常...
    風(fēng)雪圍城閱讀 465評論 0 0
  • 相愛相殺,相依為gay丙挽,可了得
    彭小菜閱讀 220評論 0 0
  • 所謂的紅顏與藍(lán)顏肺孵,就是一方蠢蠢欲動,另一方佯裝不和颜阐∑骄剑或者雙方都樂于打著友誼的旗號玩曖昧。 男女之間有沒有真正的友誼...
    煙行閱讀 555評論 9 6
  • 繼承自UIViewController IOS9.0之后正式取代UIActionsheet與UIAlertview...
    翻這個墻閱讀 724評論 0 0