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

2018-06-09  本文已影响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

上一篇下一篇

猜你喜欢

热点阅读