Java多线程 Guarded Suspension设计模式

作者:冬日毛毛雨 时间:2023-03-12 01:52:00 

前言:

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

1.Guarded Suspension模式的结构

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

  • 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

标签:Java,多线程,Guarded,Suspension
0
投稿

猜你喜欢

  • Java的Hibernate框架结合MySQL的入门学习教程

    2021-10-18 04:48:20
  • 使用Android studio创建的AIDL编译时找不到自定义类的解决办法

    2023-06-23 10:59:41
  • 如何动态修改JavaBean中注解的参数值

    2022-09-03 04:08:34
  • Spring Boot详解配置文件的用途与用法

    2022-08-01 20:37:27
  • C#线程同步的三类情景分析

    2023-01-07 22:38:04
  • 简单了解Spring中BeanFactory与FactoryBean的区别

    2022-01-14 03:59:20
  • Spring Cloud Gateway 远程代码执行漏洞(CVE-2022-22947)的过程解析

    2021-10-03 11:25:56
  • java网络编程基础知识介绍

    2023-01-10 20:37:44
  • 实例解析JAVA中代码的加载顺序

    2021-10-26 14:57:22
  • Java聊天室之实现接收和发送Socket

    2021-06-24 23:30:39
  • Java编程中字节流与字符流IO操作示例

    2022-02-23 20:35:40
  • spring-boot中使用spring-boot-devtools的实现代码

    2021-10-09 13:31:32
  • java 数据结构并查集详解

    2023-01-22 03:52:24
  • 深入了解Hadoop如何实现序列化

    2023-10-13 10:33:43
  • 关于多线程常用方法以及对锁的控制(详解)

    2022-02-02 08:16:42
  • 详解JVM之运行时常量池

    2022-08-04 03:41:03
  • 一行java代码实现高斯模糊效果

    2023-02-07 17:31:34
  • 详解Swagger接口文档和常用注解的使用

    2023-11-24 15:35:21
  • Java8新特性之精简的JRE详解_动力节点Java学院整理

    2022-09-19 12:25:50
  • 优化SpringBoot程序启动速度的实现

    2023-09-28 13:04:52
  • asp之家 软件编程 m.aspxhome.com