软件编程
位置:首页>> 软件编程>> java编程>> Java多线程 Guarded Suspension设计模式

Java多线程 Guarded Suspension设计模式

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

标签:Java,多线程,Guarded,Suspension

前言:

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

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com