Condition和AbstractQueuedSynchronizer的曖昧關系

點1:AQS即AbstractQueuedSynchronizer贴谎,內(nèi)部維護了一個CLH隊列叛溢,在JDK的lock實現(xiàn)中深受重用膏潮,詳細介紹請看,[http://www.importnew.com/22102.html]

點2:Condition,JDK API中是這樣解釋的:Condition 將 Object 監(jiān)視器方法(wait掌腰、notify 和 notifyAll)分解成截然不同的對象狰住,以便通過將這些對象與任意 Lock 實現(xiàn)組合使用,為每個對象提供多個等待 set(wait-set)齿梁。其中催植,Lock 替代了 synchronized 方法和語句的使用,Condition 替代了 Object 監(jiān)視器方法的使用。

看過ReentrantLock源碼的朋友對這兩位應該不陌生查邢,今天就和大家一起學習一下這兩個兄弟之間的CP曖昧。

Condition的使用總是伴隨著Lock的使用酵幕,先跑一個例子給大家:


image.png

image.png

執(zhí)行結果如下

image.png

一扰藕、先來分析一下 await()方法

image.png

(1)addConditionWaiter()將當前線程包裝為node維護在 condition自己的隊列中

(2)fullyRelease(node)將當前線程已經(jīng)獲取到的 lock釋放

(3)while 遍歷AQS的隊列,看當前節(jié)點是否在隊列(注意此時的隊列已經(jīng)是AQS的隊列)中芳撒,不在 說明它還沒有競爭鎖的資格邓深,所以繼續(xù)將自己沉睡。直到它被加入到隊列(AQS隊列)中笔刹,那么什么時候被加入隊列嗎芥备?這里先賣個關子。

(4)被喚醒后舌菜,重新開始正式競爭鎖萌壳,同樣,如果競爭不到還是會將自己沉睡日月,等待喚醒重新開始競爭袱瓮。

image.png

二、接下來我們看看signal方法爱咬,firstWaiter為condition自己維護的一個鏈表的頭結點尺借,取出第一個節(jié)點后開始喚醒操作

image.png

(1)著重看一下doSignal()

image.png

(2)繼續(xù)往下走,將老的頭結點精拟,加入到AQS的等待隊列中燎斩,這就是上邊賣的關子。你一定恍然大悟吧蜂绎?線程2發(fā)出signal信號后栅表,線程1就具備競爭鎖的條件了,這時候線程1就會被喚醒加入到AQS隊列中荡碾;

image.png

可以看到谨读,正常情況 ws > 0 || !compareAndSetWaitStatus(p, ws, Node.SIGNAL)這個判斷是不會為true的,所以坛吁,不會在這個時候喚醒該線程劳殖。只有到發(fā)送signal信號的線程用reentrantLock.unlock()后因為它已經(jīng)被加到AQS的等待隊列中,所以才會被喚醒拨脉。

接下來總結一下流程:

  1. 線程waitThread 先執(zhí)行調(diào)用reentrantLock.lock哆姻,獲取到了鎖,此時線程signalThread也去申請鎖時候被加入到AQS的等待隊列中玫膀。

  2. 線程waitThread調(diào)用await方法時釋放了鎖矛缨。

  3. 接著waitThread馬上被加入到Condition的等待隊列中,意味著該線程需要signal信號。

  4. 線程signalThread箕昭,因為線程waitThread釋放鎖的關系灵妨,被喚醒,并判斷可以獲取鎖落竹,于是線程signalThread獲取鎖泌霍。

  5. 線程signalThread調(diào)用signal方法,這個時候Condition的等待隊列中只有線程waitThread一個節(jié)點述召,于是它被喚醒朱转,去競爭鎖,此時線程signalThread還未釋放鎖积暖,所以只能加入到AQS的等待隊列中藤为。

  6. signal方法執(zhí)行完畢,線程signalThread調(diào)用reentrantLock.unLock()方法夺刑,釋放鎖缅疟。這個時候因為AQS中只有線程waitThread,于是遍愿,AQS釋放鎖后按從頭到尾的順序喚醒線程時窿吩,線程waitThread被喚醒,于是線程waitThread繼續(xù)執(zhí)行错览。

  7. 直到釋放所整個過程執(zhí)行完畢纫雁。

總的來看:整個過程是AQS 和Condition這哥倆的等待隊列相互移動處理來實現(xiàn)的,Condition做為條件類倾哺,內(nèi)部維護了一個等待隊列轧邪,在合適的機會將自己的隊列的節(jié)點移除并將設置到AQS隊列中,讓其去爭奪lock羞海,Condition擁有修改AQS隊列的特權忌愚。

本文參考自:http://www.importnew.com/9281.html

http://www.importnew.com/22102.html

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市却邓,隨后出現(xiàn)的幾起案子硕糊,更是在濱河造成了極大的恐慌,老刑警劉巖腊徙,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件简十,死亡現(xiàn)場離奇詭異,居然都是意外死亡撬腾,警方通過查閱死者的電腦和手機螟蝙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來民傻,“玉大人胰默,你說我怎么就攤上這事场斑。” “怎么了牵署?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵漏隐,是天一觀的道長。 經(jīng)常有香客問我奴迅,道長锁保,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任半沽,我火速辦了婚禮,結果婚禮上吴菠,老公的妹妹穿的比我還像新娘者填。我一直安慰自己,他們只是感情好做葵,可當我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布占哟。 她就那樣靜靜地躺著,像睡著了一般酿矢。 火紅的嫁衣襯著肌膚如雪榨乎。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天瘫筐,我揣著相機與錄音蜜暑,去河邊找鬼。 笑死策肝,一個胖子當著我的面吹牛肛捍,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播之众,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼拙毫,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了棺禾?” 一聲冷哼從身側響起缀蹄,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎膘婶,沒想到半個月后缺前,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡悬襟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年诡延,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片古胆。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡肆良,死狀恐怖筛璧,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情惹恃,我是刑警寧澤夭谤,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站巫糙,受9級特大地震影響朗儒,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜参淹,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一醉锄、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧浙值,春花似錦恳不、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至筐付,卻和暖如春卵惦,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背瓦戚。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工沮尿, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人较解。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓蛹找,卻偏偏與公主長得像,于是被迫代替她去往敵國和親哨坪。 傳聞我的和親對象是個殘疾皇子庸疾,可洞房花燭夜當晚...
    茶點故事閱讀 44,619評論 2 354

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