AQS的ConditionObject源碼詳解

Condition接口見Condition接口詳解

ConditionObject定義
  1. 定義為AQS的public內(nèi)部類悬蔽,方便獲取FIFO同步隊列踏烙,并將此類對象對外暴露.
  2. ** 條件等待隊列是單向隊列**:需要注意的是和AQS的FIFO的head相比椅棺,此首節(jié)點并沒有head節(jié)點信息傳播通知的功能比原,而且首節(jié)點是第一個阻塞的線程節(jié)點。
1- await方法
  1. await

步驟:

  1. 將節(jié)點加入條件等待隊列中
  2. 釋放同步狀態(tài)
  3. 死循環(huán)阻塞婶熬,直到被通知或者被中斷:1) 當(dāng)被通知喚醒時還得判斷一下當(dāng)前節(jié)點是否已經(jīng)轉(zhuǎn)移到AQS同步隊列當(dāng)中(其實主動通知的線程會確保其后繼等待節(jié)點轉(zhuǎn)移到同步隊列中剑勾,所以被通知后在下一次循環(huán)條件為false埃撵,繼續(xù)后續(xù)流程);2) 當(dāng)被中斷喚醒時需要確保節(jié)點被轉(zhuǎn)移到同步隊列中虽另,然后根據(jù)中斷發(fā)生在被通知前后位置設(shè)置中斷模式暂刘,并跳出循環(huán)。
  4. 關(guān)于中斷模式: 1) 當(dāng)在被通知前被中斷則將中斷模式設(shè)置為THROW_IE捂刺; 2) 當(dāng)在被通知后則將中斷模式設(shè)置為REINTERRUPT(因為acquireQueued不會響應(yīng)中斷)谣拣。
  5. 死循環(huán)獲取同步狀態(tài),并在同步狀態(tài)獲取成功或者取消獲取時設(shè)置中斷模式:如果在被通知之后獲取鎖過程中發(fā)生中斷則將中斷模式設(shè)置為REINTERRUPT族展。
  6. 刪除取消的后繼等待節(jié)點森缠。
  7. 根據(jù)中斷模式拋出異常。

注意:被中斷的線程跳出while循環(huán)后仪缸,會調(diào)用acquireQueued方法自旋獲取鎖贵涵,嘗試獲取同步狀態(tài),而不是立即響應(yīng)中斷拋出中斷異常恰画。在最后根據(jù)中斷模式來決定是否拋出異常宾茂。

  1. addConditionWaiter

調(diào)用await方法釋放鎖并將線程添加到條件等待隊列中并沒有采用死循環(huán)CAS設(shè)置(對比AQS.enq方法),因為Condition對象只能用于獨占模式拴还,而且在調(diào)用await之前會顯示的獲取獨占鎖跨晴,否則會拋出非法監(jiān)視器狀態(tài)異常。

  1. fullyRelease

等待的線程自沧,是已經(jīng)獲取到鎖的線程坟奥,當(dāng)線程調(diào)用wait方法時會首先釋放鎖,然后再阻塞自自身拇厢。** 當(dāng)沒有顯示的獲取鎖爱谁,直接調(diào)用await方法,會在這個方法拋出非法監(jiān)視器異常的錯誤 **孝偎。

  1. isOnSyncQueue
  • 第一個if語句:不管是因為中斷還是被通知(詳見transferAfterCancelledWait()和transferForSignal()方法)轉(zhuǎn)移到AQS同步隊列的節(jié)點狀態(tài)為都會設(shè)置為初始狀態(tài)(值為0)访敌,所以當(dāng)發(fā)現(xiàn)node.waitStatus == Node.CONDITION為真時,說明還沒有轉(zhuǎn)移到同步隊列中衣盾,返回false寺旺,在下一次while循環(huán)中判斷是否轉(zhuǎn)移成功。
  • 第二個if語句進行判斷势决,當(dāng)節(jié)點是AQS同步隊列的中間節(jié)點時(在同步隊列中含有next節(jié)點)則返回true阻塑;
  • 當(dāng)節(jié)點為尾節(jié)點時,在return語句里 果复,從后到前遍歷陈莽,如果存在則返回true,否則返回false。
  1. findNodeFromTail
  1. checkInterruptWhileWaiting

當(dāng)發(fā)生中斷走搁,則確保中斷的線程加入同步隊列中独柑,并根據(jù)transferAfterCancelledWait的返回值來設(shè)置中斷模式。

  1. reportInterruptAfterWait

如果中斷模式為THROW_IE則拋出中斷異常

  1. unlinkCancelledWaiters
  1. transferAfterCancelledWait

確保取消的節(jié)點加入同步隊列中私植,如果中斷或者超時發(fā)生在通知之前則將狀態(tài)設(shè)置為0并返回true忌栅,否則返回false。

2- awaitUninterruptibly方法
3- awaitNanos方法
4- awaitUntil方法
5- await(long time, TimeUnit unit)方法
6- signal方法




每一個被通知的節(jié)點狀態(tài)由CONDITION設(shè)置為0曲稼,并隨后確保被通知的節(jié)點在加入到同步隊列后能被前繼節(jié)點通知到(SIGNAL或者直接喚醒)索绪。

7- signalAll方法

查詢操作

8- isOwnedBy方法
9- hasWaiters方法
10- getWaitQueueLength方法
11- getWaitingThreads方法
總結(jié)
  1. 每一個創(chuàng)建的ConditionObject都維持這各自的一個單向的等待隊列,但是每個ConditionObject都共享一個AQS的FIFO同步隊列贫悄,當(dāng)調(diào)用await方法時釋放鎖并進入阻塞狀態(tài)者春,調(diào)用signal方法將條件等待隊列中的首節(jié)點線程移動到AQS同步隊列中并將其前繼節(jié)點設(shè)置為SIGNAL或者直接喚醒線程使得被通知的線程能去獲取鎖。
  2. 調(diào)用await方法釋放鎖并將線程添加到條件等待隊列中并沒有采用死循環(huán)CAS設(shè)置(參考AQS.enq方法)清女,因為Condition對象只能用于獨占模式钱烟,而且在調(diào)用await之前會顯示的獲取獨占鎖,否則會拋出非法監(jiān)視器狀態(tài)異常嫡丙。
  3. 調(diào)用signal方法將轉(zhuǎn)移等待節(jié)點拴袭,也不需要CAS來保證,因為signal會確保調(diào)用者caller是獲取獨占鎖的線程(通過isHeldExclusively方法來判斷曙博,如果為false會拋出非法監(jiān)視器狀態(tài)的異常)拥刻。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市父泳,隨后出現(xiàn)的幾起案子般哼,更是在濱河造成了極大的恐慌,老刑警劉巖惠窄,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蒸眠,死亡現(xiàn)場離奇詭異,居然都是意外死亡杆融,警方通過查閱死者的電腦和手機楞卡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來脾歇,“玉大人蒋腮,你說我怎么就攤上這事∨焊鳎” “怎么了池摧?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長激况。 經(jīng)常有香客問我作彤,道長踢京,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任宦棺,我火速辦了婚禮,結(jié)果婚禮上黔帕,老公的妹妹穿的比我還像新娘代咸。我一直安慰自己,他們只是感情好成黄,可當(dāng)我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布呐芥。 她就那樣靜靜地躺著,像睡著了一般奋岁。 火紅的嫁衣襯著肌膚如雪思瘟。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天闻伶,我揣著相機與錄音滨攻,去河邊找鬼。 笑死蓝翰,一個胖子當(dāng)著我的面吹牛光绕,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播畜份,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼诞帐,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了爆雹?” 一聲冷哼從身側(cè)響起停蕉,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎钙态,沒想到半個月后慧起,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡册倒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年完慧,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片剩失。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡屈尼,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出拴孤,到底是詐尸還是另有隱情脾歧,我是刑警寧澤,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布演熟,位于F島的核電站鞭执,受9級特大地震影響司顿,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜兄纺,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一大溜、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧估脆,春花似錦钦奋、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至圃阳,卻和暖如春厌衔,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背捍岳。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工富寿, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人锣夹。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓作喘,卻偏偏與公主長得像,于是被迫代替她去往敵國和親晕城。 傳聞我的和親對象是個殘疾皇子泞坦,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,781評論 2 354

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