官术网_书友最值得收藏!

4.3 Guarded Suspension模式實戰案例解析

某系統有一個告警[2]功能模塊。該模塊的主要功能是將其接收到的告警信息發送給告警服務器。該模塊中的類AlarmAgent負責與告警服務器進行對接。AlarmAgent的sendAlarm方法負責通過網絡連接(Socket連接)將告警信息發送給告警服務器。AlarmAgent創建了一個專門的線程用于其與告警服務器建立網絡連接。因此,在sendAlarm方法被調用的時候,連接線程可能還沒有完成網絡連接的建立。此時,sendAlarm方法應該等待連接線程建立好網絡連接。另外,即便連接線程建立好了網絡連接,中途也可能由于某些原因出現與告警服務器斷連的情況。此時,sendAlarm方法需要等待心跳(Heartbeat)任務[3]重新建立好連接后,才能上報告警信息。也就是說,sendAlarm方法必須在AlarmAgent與告警服務器的網絡連接建立成功的情況下才能執行其所要執行的操作。若AlarmAgent與告警服務器的連接未建立(或者連接中斷),sendAlarm方法的執行線程應該被暫掛直到連接建立完畢(或者恢復)。

上述問題可以應用Guarded Suspension模式來解決,如清單4-1所示。

清單4-1 AlarmAgent類源代碼

如清單4-1所示代碼中的sendAlarm方法,會等待其所屬的AlarmAgent實例連接上告警服務器后才調用doSendAlarm方法來真正地將告警信息上報給告警服務器。若在sendAlarm方法被調用時AlarmAgent實例與告警服務器的連接未建立完畢或者連接中斷了,則sendAlarm方法會使當前線程阻塞,直到其他線程喚醒該被阻塞的線程且AlarmAgent實例與告警服務器的連接建立完畢。可見,AlarmAgent實例相當于Guarded Suspension模式中的GuardedObject參與者實例,其sendAlarm方法是一個受保護方法。sendAlarm方法的目標動作是doSendAlarm所執行的操作(上報告警信息給告警服務器)。sendAlarm方法的保護條件是AlarmAgent實例與告警服務器已建立網絡連接(即connectedToServer的值為true)。

AlarmAgent的實例變量agentConnected相當于Predicate參與者實例。AlarmAgent的實例變量blocker相當于Blocker參與者實例。

AlarmAgent的onConnected方法相當于GuardedObject參與者的stateChanged方法。當告警服務器連接線程建立起與告警服務器的連接,或者心跳定時任務在網絡連接中斷后重新連接完畢時,onConnected方法都會被調用。此時,onConnected方法通過調用Blocker的實例blocker的signalAfter方法[4],將標志變量connectedToServer設置為true,并“通知”blocker去喚醒被暫掛的sendAlarm方法去執行線程。

清單4-1中的代碼所引用的其他類的源代碼,如清單4-2、清單4-3、清單4-4和清單4-5所示。

清單4-2 Predicate接口源代碼

清單4-3 GuardedAction類源代碼

清單4-4 Blocker接口源代碼

清單4-5 ConditionVarBlocker類源代碼

主站蜘蛛池模板: 望奎县| 葵青区| 龙海市| 通山县| 丹凤县| 库车县| 行唐县| 东宁县| 石家庄市| 浦江县| 宜兴市| 隆化县| 车险| 视频| 浠水县| 武宁县| 凌海市| 临西县| 军事| 抚顺县| 澳门| 莱州市| 南和县| 大悟县| 清镇市| 大兴区| 华容县| 凤山市| 临江市| 威海市| 法库县| 安阳县| 江北区| 黄陵县| 大丰市| 资兴市| 盐亭县| 韶关市| 开远市| 含山县| 砀山县|