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是继续向下执行的,可能会出现问题。