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
投稿

猜你喜欢

  • C#中Html.RenderPartial与Html.RenderAction的区别分析

    2022-03-17 01:27:59
  • Java 反射调用静态方法的简单实例

    2021-10-09 06:47:58
  • SpringBoot集成EasyExcel的步骤

    2023-07-19 09:59:17
  • java中的this引用及对象构造初始化

    2023-03-07 09:38:17
  • Android Camera2采集摄像头原始数据

    2021-06-23 22:55:53
  • Android ViewDragHelper完全解析 自定义ViewGroup神器

    2023-04-19 05:56:19
  • c#如何实现接口事件

    2023-10-02 18:31:28
  • SpringBoot 集成 activiti的示例代码

    2023-01-22 10:22:03
  • java中的FileInputStream三种read()函数用法

    2021-10-27 23:01:21
  • Java中ArrayList类的用法与源码完全解析

    2023-07-22 02:32:49
  • Android UI新组件学习和使用

    2022-04-09 01:42:03
  • Android自定义view实现输入控件

    2022-12-11 10:08:06
  • Java多线程ForkJoinPool实例详解

    2022-03-15 17:05:13
  • Android封装的http请求实用工具类

    2021-09-16 03:03:52
  • android studio 3.6 中配置svn的教程

    2022-02-26 20:59:06
  • Java BigDecimal中divide方法案例详解

    2021-12-31 07:00:29
  • Android 跨进程通Messenger(简单易懂)

    2022-03-24 00:48:25
  • Java 使用 HttpClient 发送 GET请求和 POST请求

    2023-07-23 07:56:13
  • Springboot详解实现食品仓库管理系统流程

    2023-11-10 18:33:15
  • java:程序包org.springframework.boot不存在的完美解决方法

    2023-09-03 20:37:32
  • asp之家 软件编程 m.aspxhome.com