Java并發(fā)之四:正確使用synchronized

synchronized?同步索绪,又稱同步鎖,以下簡(jiǎn)稱 "sync"凳寺。

雖然synchronized的寫(xiě)法有七八種(見(jiàn)下例)拥刻, 其實(shí)只分兩類(lèi)吴汪,一個(gè)對(duì)象實(shí)例鎖,一個(gè)類(lèi)鎖蒋腮。

對(duì)象實(shí)例鎖

1作彤、synchronized void method() :普通sync方法,鎖調(diào)用該方法的對(duì)象實(shí)現(xiàn)
2竭讳、synchronized(this) :sync this,鎖this
3、synchronized(objRef) :sync指定變量
4胰舆、synchronized(memberRef) :sync類(lèi)成員變量
5、synchronized(staticMemberRef) :sync靜態(tài)類(lèi)成員變量

類(lèi)鎖

6、synchronized static void method() :sync靜態(tài)方法
7光绕、synchronized(Sample.class) :sync類(lèi)鎖
8、synchronized(this.getClass()) :sync類(lèi)鎖

規(guī)則

1钙态、對(duì)象鎖與類(lèi)鎖互相獨(dú)立,每個(gè)實(shí)例馅袁、每個(gè)類(lèi)都只有一個(gè)鎖;

2、同為對(duì)象鎖的sync調(diào)用厌衔,判斷是否同一個(gè)對(duì)象引用,如同則存在同步競(jìng)爭(zhēng)变勇;注意Integer/String的緩存坑恤左,兩個(gè)變量實(shí)為一個(gè)。

3、同為類(lèi)鎖的sync調(diào)用飞袋,判斷是否同一個(gè)Class類(lèi)戳气,如同則存在同步競(jìng)爭(zhēng)。

4授嘀、非sync方法物咳,任何時(shí)候都不受同步鎖影響锣险。

5蹄皱、synchronized關(guān)鍵字是不能繼承的,它不是方法簽名芯肤。

6巷折、sync類(lèi)成員變量,該類(lèi)的不同實(shí)例持有的普通成員變量崖咨,對(duì)應(yīng)的是該成員變量的不同實(shí)例锻拘,它們之間是不存在鎖競(jìng)爭(zhēng)的。

7击蹲、sync靜態(tài)類(lèi)成員變量署拟,該類(lèi)的不同實(shí)例持有的是同一個(gè)成員變量實(shí)例,所以它們之間是存在鎖競(jìng)爭(zhēng)的歌豺。但與該靜態(tài)成員變量所在類(lèi)的類(lèi)鎖是互相獨(dú)立的推穷。

實(shí)現(xiàn)原理

sync同步鎖,是隱式鎖类咧,在進(jìn)入sync臨界區(qū)時(shí)由jvm自動(dòng)獲取馒铃,退出時(shí)自動(dòng)釋放。

sync同步鎖有三個(gè)屬性:
????依賴的對(duì)象實(shí)例/類(lèi)引用痕惋;(對(duì)象的鎖区宇,鎖的對(duì)象,同義)
????WaitSet值戳,等待池列表议谷,所有調(diào)用wait()方法的線程都會(huì)進(jìn)入該列表,等待池列表中的線程不會(huì)去競(jìng)爭(zhēng)sync鎖堕虹。待其他進(jìn)入sync臨界區(qū)的線程調(diào)用notify()后或wait(long)的時(shí)間到柿隙,會(huì)退出本區(qū)進(jìn)入EntryList區(qū);
????EntryList鲫凶,鎖池隊(duì)列禀崖,所有嘗試獲取sync鎖,進(jìn)入該鎖的EntryList螟炫,待當(dāng)前持有鎖的線程釋放后波附,按非公平方式分配鎖;

wait()方法只能sync臨界區(qū)內(nèi)使用,因?yàn)閣ait()的語(yǔ)義只有兩個(gè):一就是釋放sync鎖掸屡,未持有鎖談何釋放封寞;二是進(jìn)入WaitSet區(qū),等待notify或時(shí)間到仅财;

notify() 會(huì)從WaitSet列表中隨機(jī)喚醒一個(gè)狈究;

notifyAll()會(huì)將WaitSet列表中所有線程都喚醒,整體進(jìn)入鎖池去競(jìng)爭(zhēng)sync鎖盏求;

正確使用

wait() 應(yīng)配合while循環(huán)使用抖锥,不應(yīng)使用if,務(wù)必在wait()調(diào)用前后都檢查條件碎罚,如果不滿足磅废,必須調(diào)用notify()喚醒下一條線程來(lái)處理,自己回去繼續(xù)wait()直至條件滿足再往下執(zhí)行荆烈。

notifyAll()將所有WaitSet中的線程從等待池喚醒拯勉,全部進(jìn)入鎖池競(jìng)爭(zhēng)去sync鎖,最終也只有一個(gè)線程能獲取鎖去執(zhí)行憔购,喚醒+競(jìng)爭(zhēng)鎖池本身是線程上下文的重操作宫峦,對(duì)性能產(chǎn)生不良影響。濫用notifyAll()有可能導(dǎo)致“驚群效應(yīng)”玫鸟。

notify() 是對(duì)notifyAll()的一個(gè)優(yōu)化导绷,但它有很精確的應(yīng)用場(chǎng)景,并且要求正確使用鞋邑。不然可能導(dǎo)致死鎖诵次。正確的場(chǎng)景應(yīng)該是 WaitSet中等待的是相同的條件,喚醒任一個(gè)都能正確處理接下來(lái)的事項(xiàng)枚碗,如果喚醒的線程無(wú)法正確處理逾一,務(wù)必確保繼續(xù)notify()下一個(gè)線程,并且自身需要重新回到WaitSet中(參見(jiàn)上一條)肮雨。導(dǎo)致死鎖的原因是notify()隨機(jī)喚醒了一條線程遵堵,但它既無(wú)法正確改變條件,也不叫醒另一個(gè)兄弟來(lái)搞怨规,就會(huì)產(chǎn)生一個(gè)情況:鎖池中的隊(duì)列空了陌宿,等待池中有一堆線程,但不會(huì)再被喚醒永遠(yuǎn)等待波丰。


參考
? ? ? ??《Java編程思想》之《notify()vs.notifyAll()》

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末壳坪,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子掰烟,更是在濱河造成了極大的恐慌爽蝴,老刑警劉巖沐批,帶你破解...
    沈念sama閱讀 216,843評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異蝎亚,居然都是意外死亡九孩,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,538評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)发框,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)躺彬,“玉大人,你說(shuō)我怎么就攤上這事梅惯∠苡担” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,187評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵个唧,是天一觀的道長(zhǎng)江解。 經(jīng)常有香客問(wèn)我徙歼,道長(zhǎng),這世上最難降的妖魔是什么鳖枕? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,264評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮宾符,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘魏烫。我一直安慰自己辣苏,他們只是感情好哄褒,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,289評(píng)論 6 390
  • 文/花漫 我一把揭開(kāi)白布稀蟋。 她就那樣靜靜地躺著呐赡,像睡著了一般退客。 火紅的嫁衣襯著肌膚如雪链嘀。 梳的紋絲不亂的頭發(fā)上萌狂,一...
    開(kāi)封第一講書(shū)人閱讀 51,231評(píng)論 1 299
  • 那天怀泊,我揣著相機(jī)與錄音,去河邊找鬼霹琼。 笑死务傲,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的树灶。 我是一名探鬼主播纤怒,決...
    沈念sama閱讀 40,116評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼天通,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了像寒?” 一聲冷哼從身側(cè)響起烘豹,我...
    開(kāi)封第一講書(shū)人閱讀 38,945評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤诺祸,失蹤者是張志新(化名)和其女友劉穎携悯,沒(méi)想到半個(gè)月后筷笨,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體憔鬼,經(jīng)...
    沈念sama閱讀 45,367評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡胃夏,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,581評(píng)論 2 333
  • 正文 我和宋清朗相戀三年轴或,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了仰禀。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片照雁。...
    茶點(diǎn)故事閱讀 39,754評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡答恶,死狀恐怖饺蚊,靈堂內(nèi)的尸體忽然破棺而出悬嗓,到底是詐尸還是另有隱情污呼,我是刑警寧澤烫扼,帶...
    沈念sama閱讀 35,458評(píng)論 5 344
  • 正文 年R本政府宣布曙求,位于F島的核電站映企,受9級(jí)特大地震影響悟狱,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜挤渐,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,068評(píng)論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望浴麻。 院中可真熱鬧得问,春花似錦、人聲如沸宫纬。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,692評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至榛泛,卻和暖如春蝌蹂,著一層夾襖步出監(jiān)牢的瞬間曹锨,已是汗流浹背孤个。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,842評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工沛简, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留齐鲤,地道東北人覆享。 一個(gè)月前我還...
    沈念sama閱讀 47,797評(píng)論 2 369
  • 正文 我出身青樓佳遂,卻偏偏與公主長(zhǎng)得像撒顿,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子荚板,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,654評(píng)論 2 354

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

  • 本文出自 Eddy Wiki ,轉(zhuǎn)載請(qǐng)注明出處:http://eddy.wiki/interview-java.h...
    eddy_wiki閱讀 2,116評(píng)論 0 14
  • 1.解決信號(hào)量丟失和假喚醒 public class MyWaitNotify3{ MonitorObject m...
    Q羅閱讀 878評(píng)論 0 1
  • 該文章轉(zhuǎn)自:http://blog.csdn.net/evankaka/article/details/44153...
    加來(lái)依藍(lán)閱讀 7,350評(píng)論 3 87
  • 本文主要講了java中多線程的使用方法拧抖、線程同步、線程數(shù)據(jù)傳遞免绿、線程狀態(tài)及相應(yīng)的一些線程函數(shù)用法唧席、概述等嘲驾。 首先講...
    李欣陽(yáng)閱讀 2,454評(píng)論 1 15
  • 最近室友對(duì)我最常說(shuō)的話:“最近怎么總在哪里畫(huà)一畫(huà)的淌哟。” “對(duì)呀徒仓,喜歡上了,學(xué)習(xí)學(xué)習(xí)手感”我最程芄福回答的掉弛。 其實(shí)想說(shuō)我...
    畫(huà)鳴閱讀 266評(píng)論 0 2