Java:synchronized關(guān)鍵字引出的多種鎖

image

前言

Java 中的 synchronized關(guān)鍵字可以在多線程環(huán)境下用來(lái)作為線程安全的同步鎖牲览。本文不討論 synchronized 的具體使用尊浓,而是研究下synchronized底層的鎖機(jī)制宝当,以及這些鎖分別的優(yōu)缺點(diǎn)木蹬。

一 synchronized機(jī)制

synchronized關(guān)鍵字是JAVA中常用的同步功能句喷,提供了簡(jiǎn)單易用的鎖功能。
synchronized有三種用法渔期,分別為:

  • 用在普通方法上运吓,能夠鎖住當(dāng)前對(duì)象。
  • 用在靜態(tài)方法上疯趟,能夠鎖住類
  • 用在代碼塊上拘哨,鎖住的是synchronized()里的對(duì)象

在JDK6之前,synchronized使用的是重量級(jí)鎖制信峻,在之后synchronized加入了鎖膨脹機(jī)制倦青,顯著提升了synchronized關(guān)鍵字的效率。

基于synchronized關(guān)鍵字盹舞,我們來(lái)了解下幾種類別的鎖产镐,并且講解synchronized的鎖膨脹機(jī)制隘庄。

synchronized鎖是非公平鎖。并且一個(gè)被synchronized鎖住的對(duì)象或類磷账,就是一把鎖峭沦。

另外一提贾虽,所有鎖都是存儲(chǔ)在Java對(duì)象頭里的逃糟,Java對(duì)象頭里的Mark Word里默認(rèn)存儲(chǔ)對(duì)象的HashCode,分代年齡和鎖標(biāo)記位蓬豁。也就是說(shuō)Mark Word記錄了鎖的狀態(tài)

二 鎖膨脹機(jī)制與幾類鎖

鎖膨脹是不可逆的

2.1 偏向鎖

synchronized在JDK1.6以后默認(rèn)開啟偏向鎖绰咽,synchronized最初都是偏向鎖

表現(xiàn):一個(gè)線程獲取鎖成功后,會(huì)在對(duì)象頭里記錄線程ID地粪,以后該線程獲取和釋放鎖都沒(méi)有任何花費(fèi)取募。(因?yàn)樵撴i已經(jīng)被綁定在該線程上了,且在膨脹前不會(huì)改變)蟆技,如果其他線程嘗試獲取這個(gè)鎖玩敏,偏向鎖將會(huì)膨脹為輕量鎖

優(yōu)點(diǎn):在只有一個(gè)線程使用鎖的時(shí)候獲取和退出鎖沒(méi)有任何花費(fèi)

缺點(diǎn):鎖競(jìng)爭(zhēng)激烈會(huì)很快升級(jí)為輕量鎖质礼,那么維持偏向鎖的過(guò)程就是在浪費(fèi)計(jì)算機(jī)資源旺聚。(不過(guò)因?yàn)?code>偏向鎖本身就很輕量,因此浪費(fèi)的資源并不多)

小結(jié):只有一個(gè)線程使用鎖的情況下眶蕉,synchronized使用的鎖為偏向鎖砰粹。
如果鎖競(jìng)爭(zhēng)激烈,可以通過(guò)配置JDK禁用偏向鎖造挽。

2.2 輕量鎖

一把鎖不止一個(gè)線程使用碱璃,則偏向鎖膨脹為輕量鎖

表現(xiàn):線程獲取輕量鎖時(shí),會(huì)直接用CAS修改對(duì)象頭里鎖的記錄饭入,如果修改失敗嵌器,代表此時(shí)鎖存在多個(gè)線程的競(jìng)爭(zhēng),輕量鎖將會(huì)膨脹為重量鎖谐丢。

優(yōu)點(diǎn):在線程之間使用鎖不存在競(jìng)爭(zhēng)時(shí)嘴秸,一次CAS操作就能獲取和退出鎖

缺點(diǎn):與偏向鎖類似

小結(jié):只要一把鎖不止一個(gè)線程獲取過(guò),偏向鎖就會(huì)膨脹為輕量鎖庇谆。

2.3 重量鎖

一把鎖存在多線程競(jìng)爭(zhēng)岳掐,則輕量鎖開始自旋,自旋一定次數(shù)后仍沒(méi)獲取鎖饭耳,則膨脹為重量鎖(存在競(jìng)爭(zhēng)時(shí)串述,輕量鎖雖然會(huì)先自旋,但是最終往往都會(huì)膨脹為重量鎖)

表現(xiàn):線程獲取重量鎖時(shí)寞肖,如果獲取失斔ル纭(即鎖已被其他線程獲取)右蕊,則使用自適應(yīng)自旋鎖,自旋一定次數(shù)后仍沒(méi)獲取鎖吮螺,則進(jìn)入阻塞隊(duì)列等待饶囚。

優(yōu)點(diǎn):未獲取到的鎖進(jìn)入阻塞隊(duì)列,節(jié)約CPU資源鸠补。(好吧感覺(jué)其實(shí)是沒(méi)有啥優(yōu)點(diǎn))

缺點(diǎn):重量鎖是通過(guò)對(duì)象內(nèi)部的監(jiān)視器(monitor)實(shí)現(xiàn)萝风,其中monitor的本質(zhì)是依賴于底層操作系統(tǒng)的Mutex Lock實(shí)現(xiàn)紫岩,操作系統(tǒng)實(shí)現(xiàn)線程之間的切換需要從用戶態(tài)到內(nèi)核態(tài)的切換,切換成本非常高泉蝌。

小結(jié):只要一把鎖存在多線程競(jìng)爭(zhēng)歇万,輕量鎖就會(huì)膨脹為重量鎖

自旋鎖

synchronized輕量鎖勋陪,重量鎖贪磺,使用了自適應(yīng)自旋鎖進(jìn)行性能優(yōu)化

首先介紹自旋鎖

表現(xiàn):線程獲取鎖失敗后粥鞋,不會(huì)進(jìn)入阻塞等待,而是再次嘗試去獲取鎖壕曼,如此反復(fù)等浊,直到獲取到鎖,或者自旋結(jié)束那么會(huì)阻塞等待筹燕。

解決問(wèn)題:在某些場(chǎng)景下,線程持有鎖的時(shí)間非常短撒踪。在線程獲取鎖失敗后,如果線程進(jìn)入阻塞將會(huì)帶來(lái)線程上下文的切換掸绞,上下文切換的時(shí)間可能反而高于線程反復(fù)嘗試獲取鎖的時(shí)間。
此時(shí)線程原地等待去重復(fù)獲取鎖。反而在性能上更有優(yōu)勢(shì)朱嘴。

缺點(diǎn):

  1. 單核CPU沒(méi)有線程并行动分,反復(fù)嘗試會(huì)導(dǎo)致進(jìn)程無(wú)法繼續(xù)運(yùn)行捷犹。
  2. 重復(fù)嘗試導(dǎo)致了CPU的占用埃疫,如果CPU資源緊張的話反而會(huì)性能下降
  3. 如果鎖的競(jìng)爭(zhēng)時(shí)間過(guò)長(zhǎng)孩哑,不僅沒(méi)有性能提升横蜒,還浪費(fèi)了大量CPU資源。

優(yōu)化:使用自適應(yīng)自旋鎖仅炊。自適應(yīng)自旋鎖會(huì)根據(jù)之前的鎖獲取記錄抚垄,優(yōu)化調(diào)整自旋時(shí)間谋逻,避免造成不必要的自旋。

三 具體synchronized流程

image
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市纺腊,隨后出現(xiàn)的幾起案子茎芭,更是在濱河造成了極大的恐慌梅桩,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,734評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件煮寡,死亡現(xiàn)場(chǎng)離奇詭異幸撕,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)律胀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門炭菌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)黑低,“玉大人酌毡,你說(shuō)我怎么就攤上這事∑邪担” “怎么了旭蠕?”我有些...
    開封第一講書人閱讀 164,133評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵佑稠,是天一觀的道長(zhǎng)孽江。 經(jīng)常有香客問(wèn)我,道長(zhǎng)辆琅,這世上最難降的妖魔是什么这刷? 我笑而不...
    開封第一講書人閱讀 58,532評(píng)論 1 293
  • 正文 為了忘掉前任暇屋,我火速辦了婚禮,結(jié)果婚禮上扬霜,老公的妹妹穿的比我還像新娘而涉。我一直安慰自己,他們只是感情好材原,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評(píng)論 6 392
  • 文/花漫 我一把揭開白布余蟹。 她就那樣靜靜地躺著威酒,像睡著了一般话告。 火紅的嫁衣襯著肌膚如雪卵慰。 梳的紋絲不亂的頭發(fā)上裳朋,一...
    開封第一講書人閱讀 51,462評(píng)論 1 302
  • 那天鲤嫡,我揣著相機(jī)與錄音,去河邊找鬼惕耕。 笑死诫肠,一個(gè)胖子當(dāng)著我的面吹牛栋豫,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蛤铜,決...
    沈念sama閱讀 40,262評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼围肥,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了怨愤?” 一聲冷哼從身側(cè)響起蛹批,我...
    開封第一講書人閱讀 39,153評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤差导,失蹤者是張志新(化名)和其女友劉穎猪勇,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體助析,經(jīng)...
    沈念sama閱讀 45,587評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡外冀,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評(píng)論 3 336
  • 正文 我和宋清朗相戀三年雪隧,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了脑沿。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片马僻。...
    茶點(diǎn)故事閱讀 39,919評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡韭邓,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出熄诡,到底是詐尸還是另有隱情诗力,我是刑警寧澤,帶...
    沈念sama閱讀 35,635評(píng)論 5 345
  • 正文 年R本政府宣布菜拓,位于F島的核電站笛厦,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏贱鄙。R本人自食惡果不足惜逗宁,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評(píng)論 3 329
  • 文/蒙蒙 一瞎颗、第九天 我趴在偏房一處隱蔽的房頂上張望捌议。 院中可真熱鬧,春花似錦倦逐、人聲如沸弄捕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)虐秦。三九已至,卻和暖如春蜈彼,著一層夾襖步出監(jiān)牢的瞬間俺驶,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工楚昭, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留拍顷,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,048評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像踏揣,于是被迫代替她去往敵國(guó)和親呼伸。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評(píng)論 2 354

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