Guarded Suspension Pattern


Guraded Suspend Parttenは現在実行に適していない場合は、起動して実行するまで待機します.
 
クラスRequestはリクエストを表すために使用され、ここでは特別な処理はありません.
RequestQueueは、ClientThreadによって発行されたすべてのリクエストを格納するキューです.synchronizedメソッドgetRequestとputRequestが2つあり、putRequestはキューにリクエストを格納し、getRequestはキューからリクエストを取り出し、キューが空の場合は待機します.
 
public class Request {
	private String name;
	public Request(String name){
		this.name=name;
	}
	public String getName(){return name;}
	public String toString(){
		return "[Request "+name+"]";
	}
}

 
import java.util.LinkedList;

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

 
 
クラスClientThreadは、リクエストのスレッドを表すために使用され、リクエストRequest"No.0"、"No.1"、"No.2"が絶えず要求され、リクエストのRequestがキューに格納されます.
クラスサーバThreadは、キューからスレッドを継続的に読み出す処理要求です.
 
import java.util.Random;

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);
	}
	@Override
	public void run(){
		for(int i=0;i<10000;i++){
			Request request=new Request("N0."+i);
			System.out.println(Thread.currentThread().getName()+" requests "+request);
			requestQueue.putRequest(request);
			try{
				Thread.sleep(random.nextInt(1000));
			}catch(InterruptedException e){
				e.printStackTrace();
			}
		}
	}

}

 
import java.util.Random;

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);
	}
	@Override
	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){
				e.printStackTrace();
			}
		}
	}

}

実行結果:
Ally requests [Request N0.0]Bob handles [Request N0.0]Ally requests [Request N0.1]Ally requests [Request N0.2]Bob handles [Request N0.1]Bob handles [Request N0.2]Ally requests [Request N0.3]Bob handles [Request N0.3]Ally requests [Request N0.4]Bob handles [Request N0.4]Ally requests [Request N0.5]
 
ここには待機があります.つまりwhile(「警戒条件」の否定){wait待機を使用する}です.彼は条件が満たされるまで、このプロセスが続きます.
キューには2つのsynchronizedメソッドが使用されます.これは、sizeが0より大きいかどうかを判断し、queueから要素を取り出すなど、RequestQueueを保護するためのフィールドです.
このモードには3つの特徴がある:循環体の存在、条件付きテスト、何らかの理由で待っている.