- Java多線程編程實(shí)戰(zhàn)指南:設(shè)計(jì)模式篇(第2版)
- 黃文海
- 1241字
- 2021-10-15 19:24:57
4.2 Guarded Suspension模式的架構(gòu)
Guarded Suspension模式的核心是一個(gè)受保護(hù)方法(Guarded Method)。該方法在執(zhí)行其所要真正執(zhí)行的操作時(shí)需要滿足特定的條件(Predicate,以下稱之為保護(hù)條件)。當(dāng)該條件不滿足時(shí),執(zhí)行受保護(hù)方法的線程會(huì)被掛起并進(jìn)入等待(WAITING)狀態(tài),直到該條件滿足,該線程才會(huì)繼續(xù)運(yùn)行。此時(shí),受保護(hù)方法才會(huì)真正執(zhí)行其所要執(zhí)行的操作。為方便起見,以下稱受保護(hù)方法所要真正執(zhí)行的操作為目標(biāo)動(dòng)作。
Guarded Suspension模式的主要參與者有以下幾種,其類圖如圖4-1所示。

圖4-1 Guarded Suspension模式的類圖
? GuardedObject:包含受保護(hù)方法的對(duì)象,其主要方法及職責(zé)如下。
? guardedMethod:受保護(hù)方法。
? stateChanged:改變GuardedObject實(shí)例狀態(tài)的方法。該方法負(fù)責(zé)在保護(hù)條件成立時(shí)喚醒受保護(hù)方法的執(zhí)行線程。
? GuardedAction:抽象了目標(biāo)動(dòng)作,并關(guān)聯(lián)了目標(biāo)動(dòng)作所需的保護(hù)條件,其主要方法及職責(zé)如下。
? call:用于表示目標(biāo)動(dòng)作的方法。
? ConcreteGuardedAction:應(yīng)用程序所實(shí)現(xiàn)的具體目標(biāo)動(dòng)作及其關(guān)聯(lián)的保護(hù)條件。
? Predicate:抽象了保護(hù)條件,其主要方法及職責(zé)如下。
? evaluate:用于表示保護(hù)條件的方法。
? ConcretePredicate:應(yīng)用程序所實(shí)現(xiàn)的具體保護(hù)條件。
? Blocker:負(fù)責(zé)對(duì)執(zhí)行g(shù)uardedMethod方法的線程進(jìn)行掛起和喚醒,并執(zhí)行ConcreteGuardedAction所實(shí)現(xiàn)的目標(biāo)動(dòng)作,其主要方法及職責(zé)如下。
? callWithGuard:負(fù)責(zé)執(zhí)行目標(biāo)動(dòng)作和暫掛當(dāng)前線程。
? signalAfter:負(fù)責(zé)執(zhí)行其參數(shù)指定的動(dòng)作和喚醒由該方法所屬Blocker實(shí)例所暫掛的線程中的一個(gè)線程。
? broadcastAfter:負(fù)責(zé)執(zhí)行其參數(shù)指定的動(dòng)作和喚醒由該方法所屬Blocker實(shí)例所暫掛的所有線程。
? signal:負(fù)責(zé)喚醒由該方法所屬Blocker實(shí)例所暫掛的線程中的一個(gè)線程。
? broadcast:負(fù)責(zé)喚醒由該方法所屬Blocker實(shí)例暫掛的所有線程。
? ConditionVarBlocker:基于Java條件變量(java.util.concurrent.locks.Condition)實(shí)現(xiàn)的Blocker。
受保護(hù)方法的內(nèi)部處理邏輯序列圖如圖4-2所示。

圖4-2 受保護(hù)方法的內(nèi)部處理邏輯序列圖
第1步:客戶端代碼調(diào)用受保護(hù)方法guardedMethod。
第2步:guardedMethod方法創(chuàng)建GuardedAction的實(shí)例guardedAction。
第3步:guardedMethod方法以guardedAction為參數(shù)調(diào)用Blocker實(shí)例的callWithGuard方法。
第4、5步:callWithGuard方法調(diào)用guardedAction的getGuard方法獲取保護(hù)條件predicate。
第6~8步:這幾個(gè)步驟是一個(gè)循環(huán)。該循環(huán)會(huì)判斷保護(hù)條件是否成立(第6、7步)。若保護(hù)條件成立,則退出該循環(huán);否則,該循環(huán)會(huì)將當(dāng)前線程暫掛使其處于等待(WAITING)狀態(tài)(第8步)。在其他線程喚醒該被暫掛的線程后(即第8步的方法調(diào)用返回后),該循環(huán)仍然繼續(xù)檢測(cè)保護(hù)條件,并重復(fù)上述邏輯。
第9、10步:callWithGuard方法調(diào)用guardedAction的call方法來執(zhí)行目標(biāo)動(dòng)作,并記錄call方法的返回值actionReturnValue。
第11步:callWithGuard方法將actionReturnValue作為其返回值返回給調(diào)用方。
第12步:guardedMethod方法返回。
在受保護(hù)方法的執(zhí)行線程被暫掛后,當(dāng)保護(hù)條件成立時(shí),其他線程需要喚醒該線程,序列圖如圖4-3所示。

圖4-3 被暫掛線程的喚醒序列圖
第1步:客戶端代碼調(diào)用stateChanged方法改變GuardedObject實(shí)例的狀態(tài)。這些狀態(tài)包含了保護(hù)條件所關(guān)心的狀態(tài)。
第2步:stateChanged方法創(chuàng)建java.util.concurrent.Callable的實(shí)例stateOperation。stateOperation封裝了改變GuardedObject實(shí)例狀態(tài)所需的操作。
第3步:stateChanged方法以stateOperation為參數(shù),調(diào)用Blocker實(shí)例的signalAfter方法。
第4、5步:signalAfter方法調(diào)用stateOperation對(duì)象的call方法以改變GuardedObject實(shí)例的狀態(tài),并記錄其返回值shouldSignalBlocker。
第6、7步:signalAfter方法在shouldSignalBlocker值為true時(shí),調(diào)用java.util.concurrent. locks.Condition實(shí)例的signal方法來喚醒被該Condition實(shí)例所暫掛的線程中的一個(gè)線程。
第8步:signalAfter方法返回。此時(shí),執(zhí)行受保護(hù)方法的線程可能已經(jīng)被喚醒(取決于shouldSignalBlocker的值是否為true)。
第9步:stateChanged方法返回。
- 零基礎(chǔ)學(xué)Visual C++第3版
- JavaScript高效圖形編程
- Learning RxJava
- Java FX應(yīng)用開發(fā)教程
- INSTANT MinGW Starter
- Yocto for Raspberry Pi
- Web Development with MongoDB and Node(Third Edition)
- Go語言精進(jìn)之路:從新手到高手的編程思想、方法和技巧(1)
- Laravel Application Development Blueprints
- Struts 2.x權(quán)威指南
- Flask Web開發(fā):基于Python的Web應(yīng)用開發(fā)實(shí)戰(zhàn)(第2版)
- Learning Bootstrap 4(Second Edition)
- 深入淺出 HTTPS:從原理到實(shí)戰(zhàn)
- Joomla!Search Engine Optimization
- Mastering Object:Oriented Python(Second Edition)