美文网首页Java 杂谈Android技术知识Android开发经验谈
Java多线程16 Guarded Suspension设计模式

Java多线程16 Guarded Suspension设计模式

作者: 香沙小熊 | 来源:发表于2019-01-26 19:57 被阅读34次

    Java多线程目录

    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.
    

    相关文章

      网友评论

        本文标题:Java多线程16 Guarded Suspension设计模式

        本文链接:https://www.haomeiwen.com/subject/jqgijqtx.html