Guarded Suspension模式

一挤牛、定義
guarded是“被保護著的”泥张、“被防衛(wèi)著的”意思呵恢,suspension則是“暫停”的意思圾结。當(dāng)現(xiàn)在并不適合馬上執(zhí)行某個操作時瑰剃,就要求想要執(zhí)行該操作的線程等待齿诉,這就是Guarded Suspension Pattern筝野。
Guarded Suspension Pattern 會要求線程等候晌姚,以保障實例的安全性,其它類似的稱呼還有g(shù)uarded wait歇竟、spin lock等挥唠。

二、模式案例
下面的案例是一種簡單的消息處理模型焕议,客戶端線程發(fā)起請求宝磨,有請求隊列緩存請求,然后發(fā)送給服務(wù)端線程進行處理盅安。

Request類:

//request類表示請求
public class Request {
    private final String name;
    public Request(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public String toString() {
        return "[ Request " + name + " ]";
    }
}

客戶端線程類:

//客戶端線程不斷生成請求唤锉,插入請求隊列
public class ClientThread extends Thread {
    private Random random;
    private RequestQueue requestQueue;
    public ClientThread(RequestQueue requestQueue, String name, long seed) {
        super(name);
        this.requestQueue = requestQueue;
        this.random = new Random(seed);
    }
    public void run() {
        for (int i = 0; i < 10000; i++) {
            Request request = new Request("No." + i);
            System.out.println(Thread.currentThread().getName() + " requests " + request);
            requestQueue.putRequest(request);
            try {
                Thread.sleep(random.nextInt(1000));
            } catch (InterruptedException e) {
            }
        }
    }
}

服務(wù)端線程類:

//客戶端線程不斷從請求隊列中獲取請求,然后處理請求
public class ServerThread extends Thread {
    private Random random;
    private RequestQueue requestQueue;
    public ServerThread(RequestQueue requestQueue, String name, long seed) {
        super(name);
        this.requestQueue = requestQueue;
        this.random = new Random(seed);
    }
    public void run() {
        for (int i = 0; i < 10000; i++) {
            Request request = requestQueue.getRequest();
            System.out.println(Thread.currentThread().getName() + " handles  " + request);
            try {
                Thread.sleep(random.nextInt(1000));
            } catch (InterruptedException e) {
            }
        }
    }
}

請求隊列類:

public class RequestQueue {
    private final LinkedList<Request> queue = new LinkedList<Request>();
    public synchronized Request getRequest() {
        while (queue.size() <= 0) {
            try {                                   
                wait();
            } catch (InterruptedException e) {      
            }                                       
        }                                           
        return (Request)queue.removeFirst();
    }
    public synchronized void putRequest(Request request) {
        queue.addLast(request);
        notifyAll();
    }
}

注:getRequest方法中有一個判斷while (queue.size() <= 0)别瞭,該判斷稱為Guarded Suspension Pattern 的警戒條件(guard condition)窿祥。

執(zhí)行:

public class Main {
    public static void main(String[] args) {
        RequestQueue requestQueue = new RequestQueue();
        new ClientThread(requestQueue, "Alice", 3141592L).start();
        new ServerThread(requestQueue, "Bobby", 6535897L).start();
    }
}

三、模式講解
角色:
Guarded Suspension Pattern 的角色如下:

  • GuardedObject (被防衛(wèi)的對象)參與者
    GuardedObject 參與者是一個擁有被防衛(wèi)的方法(guardedMethod)的類蝙寨。當(dāng)線程執(zhí)行g(shù)uardedMethod時晒衩,只要滿足警戒條件,就能繼續(xù)執(zhí)行墙歪,否則線程會進入wait set區(qū)等待听系。警戒條件是否成立隨著GuardedObject的狀態(tài)而變化。
    GuardedObject 參與者除了guardedMethod外虹菲,可能還有用來更改實例狀態(tài)的的方法stateChangingMethod靠胜。

在Java語言中,是使用while語句和wait方法來實現(xiàn)guardedMethod的届惋;使用notify/notifyAll方法實現(xiàn)stateChangingMethod髓帽。如案例中的RequestQueue 類。

注意:Guarded Suspension Pattern 需要使用while脑豹,這樣可以使從wait set被喚醒的線程在繼續(xù)向下執(zhí)行前檢查Guard條件郑藏。如果改用if,當(dāng)多個線程被喚醒時瘩欺,由于wait是繼續(xù)向下執(zhí)行的必盖,可能會出現(xiàn)問題。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末俱饿,一起剝皮案震驚了整個濱河市歌粥,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌拍埠,老刑警劉巖失驶,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異枣购,居然都是意外死亡嬉探,警方通過查閱死者的電腦和手機擦耀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來涩堤,“玉大人眷蜓,你說我怎么就攤上這事√ノВ” “怎么了吁系?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長白魂。 經(jīng)常有香客問我汽纤,道長,這世上最難降的妖魔是什么福荸? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任冒版,我火速辦了婚禮,結(jié)果婚禮上逞姿,老公的妹妹穿的比我還像新娘辞嗡。我一直安慰自己,他們只是感情好滞造,可當(dāng)我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布续室。 她就那樣靜靜地躺著,像睡著了一般谒养。 火紅的嫁衣襯著肌膚如雪挺狰。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天买窟,我揣著相機與錄音丰泊,去河邊找鬼。 笑死始绍,一個胖子當(dāng)著我的面吹牛瞳购,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播亏推,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼学赛,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了吞杭?” 一聲冷哼從身側(cè)響起盏浇,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎芽狗,沒想到半個月后绢掰,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年滴劲,在試婚紗的時候發(fā)現(xiàn)自己被綠了谊却。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡哑芹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出捕透,到底是詐尸還是另有隱情聪姿,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布乙嘀,位于F島的核電站末购,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏虎谢。R本人自食惡果不足惜盟榴,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望婴噩。 院中可真熱鬧擎场,春花似錦、人聲如沸几莽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽章蚣。三九已至站欺,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間纤垂,已是汗流浹背矾策。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留峭沦,地道東北人贾虽。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像吼鱼,于是被迫代替她去往敵國和親榄鉴。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,901評論 2 345

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理蛉抓,服務(wù)發(fā)現(xiàn)庆尘,斷路器,智...
    卡卡羅2017閱讀 134,601評論 18 139
  • 1.接口和類 I:ExcutorI:ExcutorServiceAC:AbstractExecutorServic...
    BangAiN閱讀 2,416評論 0 2
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法巷送,類相關(guān)的語法驶忌,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法付魔,線程的語...
    子非魚_t_閱讀 31,587評論 18 399
  • 我是一個典型的90后聊品,想法多的不要不要的,行動卻也殘疾到不要不要的几苍。 我喜歡寫短的文字來表述自己的心情 就像現(xiàn)在 ...
    太陽000閱讀 198評論 0 1
  • 作為一個自詡愛好閱讀的人翻屈,每天有大量的時間使用手機閱讀。目前我的信息來源啊主要有以下幾方面1妻坝、碎片化閱讀: PC端...
    下筆有神胡不思閱讀 1,057評論 0 5