Java NIO 分析从操作系统级别讲解

246 阅读1分钟

BIO

首先了解一下各种IO模型,BIO 即Blocking IO,是一种同步阻塞IO,一个连接对要对应一个线程,即有一个客户端连接时,服务端需为其分配一个单独的线程,如果连接没有收发数据也会一直阻塞,BIO是传统的Java IO编程,在jdk1.4以前是唯一的选择

BIO编程模型

image.png

BIO 编程事例


public class BIOServer {
    public static void main(String[] args) {
        try (ServerSocket serverSocket = new ServerSocket(9000)) {
            while (!Thread.interrupted()) {
                Socket socket = serverSocket.accept();
                new Thread(new Handler(socket)).start();
            }
        } catch (IOException ioException) {
            System.out.println(ioException.getMessage());
        }
    }

    static class Handler implements Runnable {
        final Socket socket;
        Handler(Socket socket) {
            this.socket = socket;
        }
        @Override
        public void run() {
            byte[] input = new byte[1024];
            try (
                    InputStream inputStream = socket.getInputStream();
                    OutputStream outputStream = socket.getOutputStream()
            ) {
                int length;
                while ((length = inputStream.read(input)) != -1) {
                    //process service
                    byte[] output = process(input, length);
                    outputStream.write(output);
                }
            } catch (IOException e) {
                System.out.println(e.getMessage());
            }
        }

        private byte[] process(byte[] input, int length) {
            String inputString = new String(input, 0, length, StandardCharsets.UTF_8);
            System.out.println("receive message:" + new String(input, 0, length, StandardCharsets.UTF_8));
            return ("server has received message:" + inputString).getBytes(StandardCharsets.UTF_8);
        }
    }
}

BIO 缺点

以上可以看出BIO的缺点是比较明细的
  • 对第一个请求对应一个线程,无法对应高并发请求,即使加入线程池也有并发限制
  • 若无数据读取,线程是阻塞的,导致线程资源浪费

NIO

NIO 即New IO又叫 No-Blocking IO, 是同步非阻塞的,一种基于事件Reactor响应式编程模式,一个Reactor可以处理大量连接请求,基于Doug Lea "Scalable IO in Java",

NIO网络编程模型

1.单Reactor设计图

2.主从Reactor设计图

NIO编程事例

NIO源码分析

selector register accept