核心思想:
Guarded Suspension的意思是暂停保护,该模式的核心思想是仅当服务器准备好时,才提供服务。就是当大量客户请求到来,而我们不能放弃任何一个请求,必须让客户请求排队,由服务器一个一个去处理。
适用场景:
服务器请求多,但服务器程序不能丢弃任何一个客户的请求。
Guarded Suspension模式:既可以最大限度的保护服务器在大量用户访问时不挂掉,同时也能一个一个处理用户的请求 ,保证所有客户端请求均不丢失。
实例:
Request封装客户端请求。RequestQueue表示客户端请求队列(充当中间缓存,存放未处理的请求),由Client端和Server端共同维护。Client端负责不断发起请求,并将请求对象放入队列中。Server端则根据自身状态,在有能力的情况下,从RequestQueue队列中提取请求对象并进行处理。
Request类
public class Request {
private String name;
public Request(String name){
this.name = name;
}
public String getName(){
return name;
}
public String toString(){
return "[ Request " + name + " ]";
}
}
RequestQueue类
public class RequestQueue {
private LinkedList queue = new LinkedList();
public synchronized Request getRequest(){
while(queue.size() == 0){
try {
wait(); //等待直到有新的Request加入
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return (Request) queue.remove(); //返回Request队列中的第一个请求
}
public synchronized void addRequest(Request request){
queue.add(request);
notifyAll();
}
}
Server端
public class ServerThread extends Thread {
//请求队列
private RequestQueue requestQueue;
public ServerThread(RequestQueue requestQueue,String name){
super(name);
this.requestQueue =requestQueue;
}
@Override
public void run() {
while(true){
final Request request = requestQueue.getRequest();//得到请求
try {
//模拟请求处理耗时
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " handles " + request);
}
}
}
Client端
public class ClientThread extends Thread {
private RequestQueue requestQueue;
public ClientThread(RequestQueue requestQueue,String name){
super(name);
this.requestQueue = requestQueue;
}
public void run(){
for(int i =0 ;i< 10 ;i++){
Request request = new Request("RequestID:" + i +
" Thread_Name:" + Thread.currentThread().getName());
System.out.println(Thread.currentThread().getName() + " requests " + request);
//提交请求
requestQueue.addRequest(request);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("ClientThread Name is:" + Thread.currentThread().getName());
}
System.out.println(Thread.currentThread().getName() + " request end");
}
public static void main(String[] args){
RequestQueue requestQueue = new RequestQueue();
//服务器开启
for(int i = 0; i < 10; i++){
new ServerThread(requestQueue,"ServerThread" +i).start();
}
//客户端请求开启
for(int i = 0; i < 10; i++){
new ClientThread(requestQueue,"ClientThread" +i).start();
}
}
}
结果:
总结:
从上述输出过程可以看出,客户端请求过快,服务端并没有一下全部处理,而是当Client请求全部运行结束后,Server端并没有停止工作,继续处理RequestQueue中的请求,RequestQueue充当了中间缓存,这样既可以处理客户端请求,也不至于让服务端挂掉。但是又有一个问题,客户端一个个请求,此时不能获取服务器的返回结果,这个留待下一节讨论?