BiBi - 并發(fā)編程 -3- 鎖

From:Java并發(fā)編程的藝術(shù)

1. synchronized簡(jiǎn)介

synchronized內(nèi)存語義

當(dāng)線程釋放鎖時(shí),JMM會(huì)把該線程對(duì)應(yīng)的本地內(nèi)存中的共享變量刷新到主內(nèi)存中件甥。
當(dāng)線程獲取鎖時(shí)漠嵌,JMM會(huì)把該線程對(duì)應(yīng)的本地內(nèi)存置為無效,從主內(nèi)存中讀取概行。

synchronized在jvm中由monitorenter和monitorexit指令實(shí)現(xiàn)蠢挡,當(dāng)線程執(zhí)行到monitorenter指令時(shí),會(huì)去獲取所需要鎖凳忙。synchronized用的鎖存在Java對(duì)象頭里的Mark Word中业踏。

Java對(duì)象頭Mark Word的組成:鎖狀態(tài) + 對(duì)象的hashCode + 分代年齡

2. 不同級(jí)別的鎖

鎖的級(jí)別:偏向鎖 < 輕量級(jí)鎖 < 重量級(jí)鎖【只能升級(jí)不能降級(jí)】

偏向鎖 【同一線程中使用】

背景:大多數(shù)情況下,鎖不僅不存在競(jìng)爭(zhēng)涧卵,而且總是由同一線程多次獲得勤家。
特點(diǎn):在無競(jìng)爭(zhēng)情況下把整個(gè)同步都消除掉,連CAS操作都不做了柳恐。
實(shí)現(xiàn):當(dāng)一個(gè)線程訪問同步塊并獲取鎖時(shí)伐脖,會(huì)在對(duì)象頭和棧幀中的鎖記錄里使用CAS操作存儲(chǔ)偏向鎖的線程ID,以后該線程進(jìn)入和退出同步塊時(shí)不需要進(jìn)行CAS操作來加鎖和解鎖乐设,只需要測(cè)試一下對(duì)象頭的Mark Word里是否存儲(chǔ)著指向當(dāng)前線程的偏向鎖讼庇。如果成功,表示線程已經(jīng)獲取了該鎖近尚;如果測(cè)試失敗蠕啄,則需要再測(cè)試一下Mark Word中偏向鎖的標(biāo)識(shí)是否設(shè)置成1:如果沒有設(shè)置,則使用CAS競(jìng)爭(zhēng)鎖戈锻;如果設(shè)置了介汹,則嘗試使用CAS將對(duì)象頭的偏向鎖指向當(dāng)前進(jìn)程。
撤銷:只有當(dāng)其他線程嘗試競(jìng)爭(zhēng)偏向鎖時(shí)舶沛,持有偏向鎖的線程才會(huì)【在全局安全點(diǎn)嘹承,這個(gè)時(shí)間點(diǎn)不會(huì)執(zhí)行任何字節(jié)碼】釋放。如果持有鎖對(duì)象的線程已經(jīng)結(jié)束如庭,則將鎖對(duì)象恢復(fù)到未鎖定狀態(tài)叹卷;如果持有鎖對(duì)象的線程仍然活著撼港,則將鎖對(duì)象升級(jí)為輕量鎖。

提示:Java6默認(rèn)開啟偏向鎖骤竹,如果你的程序所有的鎖通常都會(huì)處于競(jìng)爭(zhēng)狀態(tài)帝牡,最好關(guān)閉偏向鎖,讓程序默認(rèn)進(jìn)入輕量級(jí)鎖狀態(tài)蒙揣。

輕量級(jí)鎖【自旋不阻塞】
  • 自旋
    背景:阻塞是互斥同步對(duì)性能最大的影響靶溜,掛起線程和恢復(fù)線程的操作需要轉(zhuǎn)入到內(nèi)核態(tài)中完成,這樣很影響性能懒震。
    實(shí)現(xiàn):線程A持有鎖罩息,而線程B要競(jìng)爭(zhēng)該鎖。通常線程A會(huì)執(zhí)行很短一段時(shí)間就會(huì)釋放鎖个扰,為了這段時(shí)間讓線程B去掛起阻塞是不值得瓷炮。此時(shí)可以讓線程B進(jìn)入自旋(死循環(huán))狀態(tài),等線程A釋放鎖后递宅,線程B直接獲取娘香。【前提是在多處理器情況下办龄,線程A和B占用不同的處理器烘绽,一直在消耗資源。阻塞不會(huì)消耗資源俐填,但性能差】

輕量級(jí)鎖的實(shí)現(xiàn):線程在執(zhí)行同步塊之前安接,JVM現(xiàn)在當(dāng)前線程的棧楨中創(chuàng)建用于存儲(chǔ)鎖記錄的空間,并將對(duì)象頭中的Mark Word復(fù)制到鎖記錄中玷禽,稱為Dispatch Mark Word。然后線程嘗試使用CAS將對(duì)象頭中的Mark Word替換為指向鎖記錄的指針呀打。如果成功矢赁,當(dāng)前線程獲得鎖,如果失敗贬丛,表示存在其他線程的競(jìng)爭(zhēng)撩银,當(dāng)前線程嘗試使用自旋來獲取鎖。

3. 不同鎖的使用場(chǎng)景

重量級(jí)鎖:線程競(jìng)爭(zhēng)不會(huì)自旋豺憔,不會(huì)消耗CUP额获,但線程會(huì)阻塞,響應(yīng)時(shí)間慢【適用于追求吞吐量恭应,同步塊執(zhí)行時(shí)間較長(zhǎng)的場(chǎng)景】
輕量級(jí)鎖:競(jìng)爭(zhēng)的線程不會(huì)阻塞抄邀,響應(yīng)快,但得不到鎖競(jìng)爭(zhēng)的線程使用自旋消耗CUP【適用于追求響應(yīng)時(shí)間昼榛,同步塊執(zhí)行時(shí)間較少的場(chǎng)景】
偏向鎖:加鎖和解鎖不需要額外的消耗境肾,但如果存在競(jìng)爭(zhēng)會(huì)帶來額外的鎖撤銷消耗【適用于只有一個(gè)線程,競(jìng)爭(zhēng)少的場(chǎng)景】

4. 鎖優(yōu)化

鎖消除
public void fun(){
  StringBuffer sb = new StringBuffer();
  sb.append("a");
  sb.append("b");
}

變量sb的作用域在方法fun中,不會(huì)“逃逸”奥喻,其它線程無法訪問到偶宫,所以編譯器會(huì)消除append()方法的同步處理。

鎖粗化

對(duì)于零碎使用同一個(gè)鎖的操作环鲤,編譯器會(huì)把鎖同步的范圍進(jìn)行擴(kuò)展纯趋。

5. 悲觀/樂觀鎖

悲觀鎖

總是假設(shè)最壞的情況,每次取數(shù)據(jù)時(shí)都認(rèn)為其他線程會(huì)修改冷离,所以都會(huì)加鎖左驾。一旦加鎖倡鲸,不同線程同時(shí)執(zhí)行時(shí),只能有一個(gè)線程執(zhí)行,其他的線程在入口處等待甫菠,直到鎖被釋放。

樂觀鎖

樂觀鎖顧名思義就是在操作時(shí)很樂觀解幼,認(rèn)為操作不會(huì)產(chǎn)生并發(fā)問題(不會(huì)有其他線程對(duì)數(shù)據(jù)進(jìn)行修改)外永,因此不會(huì)上鎖。但是在更新時(shí)會(huì)判斷其他線程在這之前有沒有對(duì)數(shù)據(jù)進(jìn)行修改匙铡,一般會(huì)使用版本號(hào)機(jī)制或CAS算法實(shí)現(xiàn)图甜。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市鳖眼,隨后出現(xiàn)的幾起案子黑毅,更是在濱河造成了極大的恐慌,老刑警劉巖钦讳,帶你破解...
    沈念sama閱讀 219,188評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件矿瘦,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡愿卒,警方通過查閱死者的電腦和手機(jī)缚去,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來琼开,“玉大人易结,你說我怎么就攤上這事」窈颍” “怎么了搞动?”我有些...
    開封第一講書人閱讀 165,562評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)渣刷。 經(jīng)常有香客問我鹦肿,道長(zhǎng),這世上最難降的妖魔是什么辅柴? 我笑而不...
    開封第一講書人閱讀 58,893評(píng)論 1 295
  • 正文 為了忘掉前任狮惜,我火速辦了婚禮高诺,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘碾篡。我一直安慰自己虱而,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評(píng)論 6 392
  • 文/花漫 我一把揭開白布开泽。 她就那樣靜靜地躺著牡拇,像睡著了一般。 火紅的嫁衣襯著肌膚如雪穆律。 梳的紋絲不亂的頭發(fā)上惠呼,一...
    開封第一講書人閱讀 51,708評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音峦耘,去河邊找鬼剔蹋。 笑死,一個(gè)胖子當(dāng)著我的面吹牛辅髓,可吹牛的內(nèi)容都是我干的泣崩。 我是一名探鬼主播,決...
    沈念sama閱讀 40,430評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼洛口,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼矫付!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起第焰,我...
    開封第一講書人閱讀 39,342評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤买优,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后挺举,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體杀赢,經(jīng)...
    沈念sama閱讀 45,801評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評(píng)論 3 337
  • 正文 我和宋清朗相戀三年湘纵,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了脂崔。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,115評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡瞻佛,死狀恐怖脱篙,靈堂內(nèi)的尸體忽然破棺而出娇钱,到底是詐尸還是另有隱情伤柄,我是刑警寧澤,帶...
    沈念sama閱讀 35,804評(píng)論 5 346
  • 正文 年R本政府宣布文搂,位于F島的核電站适刀,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏煤蹭。R本人自食惡果不足惜笔喉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評(píng)論 3 331
  • 文/蒙蒙 一取视、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧常挚,春花似錦作谭、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至吼过,卻和暖如春锐秦,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背盗忱。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工酱床, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人趟佃。 一個(gè)月前我還...
    沈念sama閱讀 48,365評(píng)論 3 373
  • 正文 我出身青樓扇谣,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親揖闸。 傳聞我的和親對(duì)象是個(gè)殘疾皇子揍堕,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評(píng)論 2 355