guarded是「被保護着的」、「被防衛着的」意思,suspension則是「暫停」的意思。當如今並不適合立刻執行某個操做時,就要求想要執行該操做的線程等待,這就是Guarded Suspension Pattern。
Guarded Suspension Pattern 會要求線程等候,以保障實例的安全性,其它相似的稱呼還有guarded wait、spin lock等。緩存
下面的案例是一種簡單的消息處理模型,客戶端線程發起請求,有請求隊列緩存請求,而後發送給服務端線程進行處理。安全
Request類:dom
//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 + " ]"; } }
客戶端線程類:this
//客戶端線程不斷生成請求,插入請求隊列 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) { } } } }
服務端線程類:spa
//客戶端線程不斷從請求隊列中獲取請求,而後處理請求 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)。code
執行:對象
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 的角色以下:blog
GuardedObject 參與者是一個擁有被防衛的方法(guardedMethod)的類。當線程執行guardedMethod時,只要知足警惕條件,就能繼續執行,不然線程會進入wait set區等待。警惕條件是否成立隨着GuardedObject的狀態而變化。
GuardedObject 參與者除了guardedMethod外,可能還有用來更改實例狀態的的方法stateChangingMethod。隊列
在Java語言中,是使用while語句和wait方法來實現guardedMethod的;使用notify/notifyAll方法實現stateChangingMethod。如案例中的RequestQueue 類。
注意:Guarded Suspension Pattern 須要使用while,這樣能夠使從wait set被喚醒的線程在繼續向下執行前檢查Guard條件。若是改用if,當多個線程被喚醒時,因爲wait是繼續向下執行的,可能會出現問題。