Java多线程 Guarded Suspension设计模式
作者:冬日毛毛雨 发布时间:2023-03-12 01:52:00
前言:
Guarded Suspension
意为保护暂停,其核心思想是仅当服务进程准备好时,才提供服务。设想一种场景,服务器可能会在很短时间内承受大量的客户端请求,客户端请求的数量可能超过服务器本身的即时处理能力,而服务端程序又不能丢弃任何一个客户请求。此时,最佳的处理方案莫过于让客户端要求进行排队,由服务端程序一个接一个处理。这样,既保证了所有的客户端请求均不丢失,同时也避免了服务器由于同时处理太多的请求而崩溃
1.Guarded Suspension模式的结构
Guarded Suspension模式的主要成员有:Request
、RequestQueue
、ClientThread
、 ServerThread
Request
:表示客户端请求RequestQueue
:用于保存客户端请求队列ClientThread
:客户端进程ServerThread
:服务器进程
其中,ClientThread
负责不断发起请求,并将请求对象放入请求队列。ServerThread
则根据其自身的状态,在有能力处理请求时,从RequestQueue
中提取请求对象加以处理。
从流程图中可以看到,客户端的请求数量超过了服务线程的能力。在频繁的客户端请求中,RequestQueue
充当了中间缓存,存放未处理的请求,保证了客户请求不丢失,同时也保护了服务线程不会受到大量并发的请求,而导致计算机资源不足
2. Guarded Suspension模式的简单实现
public class ClientThread extends Thread {
private final RequestQueue queue;
private final Random random;
private final String sendValue;
public ClientThread(RequestQueue queue, String sendValue) {
this.queue = queue;
this.sendValue = sendValue;
this.random = new Random(System.currentTimeMillis());
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("Client -> request " + sendValue);
queue.putRequest(new Request(sendValue));
try {
Thread.sleep(random.nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Request {
private final String value;
public Request(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
public class RequestQueue {
private final LinkedList<Request> queue = new LinkedList<>();
public Request getRequest() {
synchronized (queue) {
while (queue.size() <= 0) {
try {
queue.wait();
} catch (InterruptedException e) {
return null;
}
}
return queue.removeFirst();
}
}
public void putRequest(Request request) {
synchronized (queue) {
queue.addLast(request);
queue.notifyAll();
}
}
}
public class ServerThread extends Thread {
private final RequestQueue queue;
private final Random random;
private volatile boolean closed = false;
public ServerThread(RequestQueue queue) {
this.queue = queue;
random = new Random(System.currentTimeMillis());
}
@Override
public void run() {
while (!closed) {
Request request = queue.getRequest();
if (null == request) {
System.out.println("Received the empty request.");
continue;
}
System.out.println("Server ->" + request.getValue());
try {
Thread.sleep(random.nextInt(1000));
} catch (InterruptedException e) {
return;
}
}
}
public void close() {
this.closed = true;
this.interrupt();
}
}
public class SuspensionClient {
public static void main(String[] args) throws InterruptedException {
final RequestQueue queue = new RequestQueue();
new ClientThread(queue,"Jack").start();
ServerThread serverThread = new ServerThread(queue);
serverThread.start();
Thread.sleep(10000);
serverThread.close();
}
}
运行:
Client -> request Jack
Server ->Jack
Client -> request Jack
Server ->Jack
Client -> request Jack
Server ->Jack
Client -> request Jack
Server ->Jack
Client -> request Jack
Client -> request Jack
Client -> request Jack
Server ->Jack
Client -> request Jack
Client -> request Jack
Server ->Jack
Client -> request Jack
Server ->Jack
Server ->Jack
Server ->Jack
Server ->Jack
Received the empty request.
来源:https://juejin.cn/post/7022609159912685575
猜你喜欢
- SpringBoot @NotBlank错误java 验证出现如下错误:javax.validation.UnexpectedTypeExc
- 采集器概貌,如下:最近做一个项目,功能类似于CNZZ站长统计功能,要求显示Ip所在的省份市区/提供商等信息。网上的Ip纯真数据库,下载下来一
- 主要是重写attemptAuthentication方法导入依赖<dependency><groupId>org.s
- 二维码是什么二维码 QR Code,全称为:Quick Response Code,最早用于日本汽车制造业追踪零部件。QR现有40个标准版本
- 前言在实际生活中,地图是我们经常使用的一种工具,通常我们会用它进行导航,输入一个出发城市,输入一个目的地城市,就可以把路线规划好,而在规划好
- 简要:EigenFace是基于PCA降维的人脸识别算法,PCA是使整体数据降维后的方差最大,没有考虑降维后类间的变化。 它是将图像
- 前言什么是mybatis二级缓存?二级缓存是多个sqlsession共享的,其作用域是mapper的同一个namespace。即,在不同的s
- 简介happens-before是JMM的核心概念。理解happens-before是了解JMM的关键。1、设计意图JMM的设计需要考虑两个
- 问题描述:在用fabric集成后编译出现如下错误,Error:Cause: hostname in certificate didn'
- Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spri
- 前言Json反序列化有两种方式【本人】,一种是生成实体的,方便处理大量数据,复杂度稍高,一种是用匿名类写,方便读取数据,较为简单。使用了Ne
- java有两种类型的classload,一种是user-defined的,一种是jvm内置的bootstrap class loader,所
- 之前学习 Java 的时候,感觉最难做的一件事情就是配置 jdk 的环境。那叫一个困难啊,Path, JAVA_HOME, CLASSPAT
- 本文实例讲述了WinForm中实现picturebox自适应图片大小的方法。分享给大家供大家参考,具体如下:picturebox控件共有两种
- 这篇文章需要一定Vue和SpringBoot的知识,分为两个项目,一个是前端Vue项目,一个是后端SpringBoot项目。后端项目搭建我使
- 什么是线程同步? 当使用多个线程来访问同一个数据时,非常容易出现线程安全问题(比如多个线程都在操作同一数据导致数据不一致),所以我们用同步机
- JavaBean根据指定条件设置属性值默认值使用场景当bean数据中已经装配好其他数据,在逻辑以及数据转换完成的最后一步进行数据默认值设置;
- 前言环境: flutter sdk v1.7.8+hotfix.3@stable对应 flutter engine: 54ad777f这里关
- 首先,类只能使用public修饰是一个伪命题,应该说我们只见到过使用public修饰的类,还有一些类没有访问修饰符,此时访问权限为defau
- 本文开始做一个网上商城的项目,首先从搭建环境开始,一步步