Guarded是被守护、被保卫、被保护的意思,
Suspension则是暂停的意思。
如果执行现在的处理会造成问题,
就让执行处理的线程进行等待---
这就是Guarded Suspension模式。
模式通过让线程等待来保证实例的安全性。
一个线程ClientThread会将请求
Request的实例传递给另一个线程
ServerThread。这是一种最简单的线程
间通信。
Request ? ? ? ?表示一个请求的类
RequestQueue ? 依次存放请求的类
ClientThread ? 发送请求的类
ServerThread。 接收请求的类
Main ? ? ? ? ? 测试程序行为的类
RequestQueue类
用于依次存放请求。
该类种定义了getRequest和
putRequest这两个方法。
getRequest方法会取出最先存放在
RequestQueue的一个请求,作为其返回值。
如果一个请求都没有,那就一直等待,
直到其他某个线程执行putRequest.
putRequest方法
用于添加一个请求。当线程想要向
RequestQueue种添加Request实例时
,可以调用该方法。
public class ClientThread extends Thread{
private final Random random;
private final 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) {
throw new RuntimeException(e);
}
}
}
}
public class Request {
private final String name;
public Request(String name){
this.name = name;
}
public String toString(){
return "[ Request " + name +" ]";
}
}
public class RequestQueue {
private final Queue<Request> queue = new LinkedList<Request>();
public synchronized Request getRequest() {
while(queue.peek() == null) {
try {
wait();
} catch (InterruptedException e) {
}
}
return queue.remove();
}
public synchronized void putRequest(Request request){
queue.offer(request);
notifyAll();
}
}
public class ServiceThread extends Thread {
private final Random random;
private final RequestQueue requestQueue;
public ServiceThread(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){
}
}
}
}