Java程序性能优化 读书笔记(十二)并行设计模式:Guarded Suspension模式
来源:互联网 发布:吉利知豆d3四座 编辑:程序博客网 时间:2024/05/22 02:08
一、Guarded Suspension模式
Guarded Suspension意为保护暂停,其核心思想是仅当服务进程准备好时,才提供服务。设想一种场景,服务器可能会在很短时间内承受大量的客户端请求,客户端请求的数量可能超过服务器本身的即时处理能力,而服务端程序又不能丢弃任何一个客户请求。此时,最佳的处理方案莫过于让客户端要求进行排队,由服务端程序一个接一个处理。这样,既保证了所有的客户端请求均不丢失,同时也避免了服务器由于同时处理太多的请求而崩溃。
二、Guarded Suspension模式的结构
Guarded Suspension模式的主要成员有:Request、RequestQueue、ClientThread、ServerThread
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提高系统的抗压能力和稳定性有一定的帮助。
- Java程序性能优化 读书笔记(十二)并行设计模式:Guarded Suspension模式
- 并行-Guarded Suspension模式
- Java 并行程序设计模式 (Guarded Suspension模式)
- Guarded Suspension设计模式
- java多线程设计模式之Guarded Suspension
- Java 多线程设计模式之Guarded Suspension
- 设计模式之多线程模式Guarded Suspension
- 多线程设计模式之Guarded Suspension模式
- 并发设计模式之Guarded Suspension模式
- Java程序性能优化 读书笔记(十)并行设计模式:Future模式
- Java程序性能优化 读书笔记(十一)并行设计模式:Master-Worker模式
- Java程序性能优化 读书笔记(十三)并行设计模式:不变模式
- Java程序性能优化 读书笔记(十四)并行设计模式:生产者-消费者模式
- 《java多线程设计模式 第三章Guarded Suspension Pattern》
- Guarded Suspension 模式
- Guarded Suspension Patten ----java多线程模式(三)
- Java中的线程(六)- Guarded Suspension 模式
- 保护性暂挂模式(Guarded Suspension)
- shell docker 镜像推送的使用
- Navicat连接数据库Can't get hostname for your address 解决方法
- 新生代的配置
- (二)从零搭建maven+spring+mybatis项目之web项目创建
- 深入理解Spring4框架(三)——Bean
- Java程序性能优化 读书笔记(十二)并行设计模式:Guarded Suspension模式
- PTA 7-1 树的同构(25 分)
- Windows下安装Ubuntu 16.04双系统
- 关于多个按钮更改程序执行状态的实验
- linux测试题总结
- HDU
- 文章标题
- SPARK中实现用户自定义排序
- c语言入门:用for循环输出乘法口诀表