美文网首页
I/O系列篇(二)伪异步I/O

I/O系列篇(二)伪异步I/O

作者: 无量散人 | 来源:发表于2018-06-09 12:40 被阅读31次

    一、模型说明

    1、伪异步I/O模型的模型图

    image.png

    2、相对于BIO的改进点

    伪异步I/O模型采用线程池和队列技术,解决了BIO由于客户端请求量过大时,导致服务端资源耗尽和宕机的问题。因为伪异步线程模型,当有新的客户端接入的时候,将客户端的socket封装成一个Task(线程对象),投递给后端的线程池处理,线程池维护一个消息队列和N个活跃的线程,对消息队列中的任务进行处理,由于线程池可以设置大小和最大线程数,所以占用的资源是可控的,无论多少个客户端并发访问,都不会导致资源耗尽和宕机。

    3、伪异步I/O的弊端

    由于底层通信仍然采用的是同步阻塞模型,所以从根本上无法解决问题。通过对输入、输出流的API文档进行分析,了解到读和写仍然是同步阻塞的,阻塞的时间取决于对方线程的I/O处理速度和网络I/O传输速度。从本质上讲,我们无法保证生产环境的网络状况和对方的应用程序足够快,如果我们的应用程序严重依赖于对方的处理速度,那么可靠性就非常的差。


    二、代码

    1、服务端代码

    public class TimeServer {
    
        public static void main(String[] args) throws IOException {
            int port = 8080;
    
            ServerSocket server = null;
            try {
    
                server = new ServerSocket(port);
    
                System.out.println("the time server is start in port : " + port);
    
                Socket socket = null;
                TimerServerHandlerExecutePool threadPool = new TimerServerHandlerExecutePool(50,10000);
    
                while (true){
                    socket = server.accept();
                    threadPool.execute(new Thread(new TimeServerHandler(socket)));
                }
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                if (server!=null){
                    server.close();
                    server = null;
                }
            }
        }
    }
    
    public class TimerServerHandlerExecutePool {
    
        private ExecutorService executor;
    
        public TimerServerHandlerExecutePool(int maxPoolSize, int queueSize){
            executor = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(),
                    maxPoolSize,
                    120L,
                    TimeUnit.SECONDS,
                    new ArrayBlockingQueue<Runnable>(queueSize));
        }
    
        public void execute(Runnable task){
            executor.execute(task);
        }
    }
    

    2、客户端代码

    public class TimerClient {
    
        public static void main(String[] args) {
            int port = 8080;
            Socket socket = null;
            BufferedReader in = null;
            PrintWriter out = null;
            try {
                socket = new Socket("127.0.0.1", port);
    
                in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                out = new PrintWriter(socket.getOutputStream(), true);
    
                out.println("what time is now ?");
    
                System.out.println("the time client send msg succeed");
    
                String responsStr = in.readLine();
    
                System.out.println("the time server response --- " + responsStr);
    
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                if (out!=null){
                    out.close();
                    out = null;
                }
                if (in!=null){
                    try {
                        in.close();
                        in = null;
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (socket!=null){
                    try {
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    socket = null;
                }
            }
        }
    }
    


    三、运行结果

    1、服务端

    the time server is start in port : 8080
    the time server receive msg : what time is now ?

    2、客户端

    the time client send msg succeed
    the time server response --- now time is : 1528519169887

    相关文章

      网友评论

          本文标题:I/O系列篇(二)伪异步I/O

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