Java程序性能优化 读书笔记(十二)并行设计模式:Guarded Suspension模式

来源:互联网 发布:吉利知豆d3四座 编辑:程序博客网 时间:2024/05/22 02:08


一、Guarded Suspension模式

Guarded Suspension意为保护暂停,其核心思想是仅当服务进程准备好时,才提供服务。设想一种场景,服务器可能会在很短时间内承受大量的客户端请求,客户端请求的数量可能超过服务器本身的即时处理能力,而服务端程序又不能丢弃任何一个客户请求。此时,最佳的处理方案莫过于让客户端要求进行排队,由服务端程序一个接一个处理。这样,既保证了所有的客户端请求均不丢失,同时也避免了服务器由于同时处理太多的请求而崩溃。


二、Guarded Suspension模式的结构

Guarded Suspension模式的主要成员有:RequestRequestQueueClientThreadServerThread

Request:表示客户端请求

RequestQueue:用于保存客户端请求队列

ClientThread:客户端进程

ServerThread:服务器进程

其中,ClientThread负责不断发起请求,并将请求对象放入请求队列。ServerThread则根据其自身的状态,在有能力处理请求时,从RequestQueue中提取请求对象加以处理。系统的工作流程如图


三、Guarded Suspension模式的实现

Request类封装了请求的内容

package com.zenhobby; public class Request {private String name;public Request(String name) {this.name = name;}public String getName() {return name;}@Overridepublic String toString() {return "[ Request "+ name + " ]"; }}
RequestQueue对象作为Request的集合,维护系统的Request请求列表
package com.zenhobby; import java.util.LinkedList; public class RequestQueue {private LinkedList<Request> queue = new LinkedList<>();public synchronized Request getRequest() {while (queue.size() == 0) {try {wait();} catch (InterruptedException e) {e.printStackTrace();}}return queue.removeFirst();}public synchronized void addRequest(Request request) {queue.add(request);notifyAll();}}
服务端进程用于处理用户的请求操作,代码实现如下

package com.zenhobby; public class ServerThread extends Thread {private RequestQueue requestQueue;public ServerThread(RequestQueue requestQueue, String name) {super(name);this.requestQueue = requestQueue;}@Overridepublic 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);}}}
客户端的请求发起进程代码实现如下

package com.zenhobby; public class ClientThread extends Thread {private RequestQueue requestQueue;public ClientThread(RequestQueue requestQueue, String name) {super(name);this.requestQueue = requestQueue;}@Overridepublic 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");}}
主函数如下
package com.zenhobby; public class Main {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();}}}

RequestQueue起到了中间缓存的作用,从程序执行结果来看,当所有的ClientThread全部运行结束后,Server进程并没有停止工作,而是继续处理RequestQueue中的请求,直至处理完毕,Client的请求并未丢失。

四、带返回值的Guarded Suspension模式

上述的Guarded Suspension模式中Request'的请求并无返回值,因此客户端无法得知请求的执行情况,因此采用Future模式对Guarded Suspension模式进行增强可以构造带返回值的Guarded Suspension模式。

首先,客户进程和服务进程对于请求队列的处理和改进前完全一致,只是服务进程在数据处理时添加了对Request中response的数据处理,服务进程会在其工作过程中将返回数据设置到response中,当客户端访问数据时若服务进程尚未完成,则客户端需要等待,否则客户端直接获取数据,与Future模式一致。

将原模式中的Request类进行扩展,嵌入Future模式中的Data接口,用于传递服务器返回的数据。

package com.zenhobby; public class Request {private String name;private Data response;public synchronized Data getResponse(){return response;}public synchronized void setResponse(Data response){this.response = response;}public Request(String name) {this.name = name;}public String getName() {return name;}@Overridepublic String toString() {return "[ Request "+ name + " ]"; }}

Data类的实现与Future中的实现完全一致;

Server中需要添加对返回值的处理

package com.zenhobby; public class ServerThread extends Thread {private RequestQueue requestQueue;public ServerThread(RequestQueue requestQueue, String name) {super(name);this.requestQueue = requestQueue;}@Overridepublic void run() {while (true) {final Request request = requestQueue.getRequest();final FutureData future = (FutureData)request.getResponse();RealData realdata = new RealData(request.getName());future.setRealData(realdata);System.out.println(Thread.currentThread().getName() + " handles " + request);}}}
客户端中也要添加对返回值的处理

package com.zenhobby; public class ClientThread extends Thread {private RequestQueue requestQueue;private List<Request> myRequest = new ArrayList<Request>();public ClientThread(RequestQueue requestQueue, String name) {super(name);this.requestQueue = requestQueue;}@Overridepublic 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);//设置一个FutureData的返回值request.setResponse(new FutureData());requestQueue.addRequest(request);myRequest.add(request);try {Thread.sleep(1000);  //做一些额外的业务等待服务器装配数据} catch (InterruptedException e) {e.printStackTrace();}for (Request r:myRequest) {System.out.println("ClientThread Name is:"+Thread.currentThread().getName()+" Response is:"+r.getResponse().getResult);//阻塞等待结果}}}}
Guarded Suspension模式在一定程度上可以缓解系统的压力,它可以将系统的负载在时间轴上均匀地分配,降低系统的瞬时负载,UI提高系统的抗压能力和稳定性有一定的帮助。








阅读全文
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 澳洲两年工作签怎么办 上班一年没签劳动合同怎么办 公司拖欠工资怎么办没签劳动合同 brp丢了怎么办回国补 被怀疑假结婚该怎么办 中考作弊被捉了怎么办 露娜注册错了怎么办 去泰国开民宿怎么办工作签证 绩点2.7想出国怎么办 香港过境想去澳门怎么办 加拿大博士资格考试没通过怎么办 外国人没有学历怎么办工作签证 澳洲语言班挂了怎么办 英国学位翻译成文学硕士怎么办 没考上好的高中怎么办 毕业证12月发放申请英国怎么办 高二迷茫成绩差怎么办 高二期末考的差怎么办 法国留学签证办不下来怎么办 澳洲留学挂科签证续签怎么办 澳洲旅游签证被拒了怎么办 学校六级不让刷分怎么办 英国留学生怎么办申根签证 挂科太多拿不到学位证怎么办 ucl语言班没过怎么办 西澳大学工程挂科怎么办 澳洲语言班没过怎么办2018 杨浦区对口公立小学太差怎么办 公立小学太差了怎么办 澳大利亚出国留学怎么办-语言课程 学校不给释放信怎么办 重修费交不起钱怎么办 不想用家里的钱怎么办 三本学费太贵怎么办 从日本往中国汇款怎么办 学费钱大一没交怎么办 初中孩子和同学相处不好怎么办 使用假护照出国被发现怎么办 酒店忘记退房了怎么办 语言课申请不上怎么办 学会计的应届生想转行怎么办