BIO、NIO、AIO

BIO

概念:
BIO 是传统的同步阻塞 I/O,每个请求都需要一个独立的线程来处理。
BIO 适用于连接数较少的场景,因为每个 I/O 操作都会阻塞线程,导致资源消耗较大。

  • 每个 I/O 操作(如 read()write())都会阻塞,直到数据准备好或操作完成。
  • 每个客户端连接都需要一个独立的线程来处理(典型的 "一线程一连接" 模型)。

例:传统的socket编程

ServerSocket serverSocket = new ServerSocket(8080);
while (true) {
    Socket socket = serverSocket.accept(); // 阻塞等待连接
    new Thread(() -> {
        try (InputStream in = socket.getInputStream(); 
             OutputStream out = socket.getOutputStream()) {
            byte[] buffer = new byte[1024];
            int len = in.read(buffer); // 阻塞等待数据
            out.write(buffer, 0, len);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }).start(); // 每个请求都创建一个新线程处理
}

NIO

概念:
NIO 是同步非阻塞 I/O,使用 Selector 轮询多个通道(Channel),一个线程可以管理多个连接,提高了 I/O 处理效率。
NIO 适用于高并发场景,如聊天服务器、消息推送等。

  • 数据读取/写入不会阻塞线程,即使数据未准备好,线程也不会一直等待。
  • 一个线程可以同时监听多个通道,提高了资源利用率。
  • 通过多路复用(Selector)机制来管理多个通道(Channel),监听它们的状态变化,从而避免传统 BIO 模型中的阻塞问题。

例:

Selector selector = Selector.open();
ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.configureBlocking(false);
serverChannel.bind(new InetSocketAddress(8080));
serverChannel.register(selector, SelectionKey.OP_ACCEPT);

while (true) {
    selector.select(); // 阻塞等待事件
    Set<SelectionKey> keys = selector.selectedKeys();
    Iterator<SelectionKey> iterator = keys.iterator();
    
    while (iterator.hasNext()) {
        SelectionKey key = iterator.next();
        iterator.remove();
        
        if (key.isAcceptable()) {
            SocketChannel client = serverChannel.accept();
            client.configureBlocking(false);
            client.register(selector, SelectionKey.OP_READ);
        } else if (key.isReadable()) {
            SocketChannel client = (SocketChannel) key.channel();
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            client.read(buffer);
            buffer.flip();
            client.write(buffer); // 回写数据
        }
    }
}

NIO它有多种模式:

单线程 Reactor
  • 适用于低并发场景,一个线程同时处理连接和 I/O,但容易阻塞。
多线程 Reactor
  • Boss 线程(单个):负责监听新连接,并将 SocketChannel 分配给 Worker 线程。
  • Worker 线程(多个):每个 Worker 线程维护一个 Selector,负责多个 Channel 的 I/O 读写操作。
Netty 的多线程 Reactor 
  • BossGroup(NioEventLoopGroup)处理连接请求。
  • WorkerGroup(NioEventLoopGroup)管理多个 Selector,处理 I/O 操作。
  • 每个 Worker 线程对应一个 Selector,每个 Selector 负责多个 Channel

AIO

概念:
AIO 是真正的异步 I/O,使用回调方式(CompletionHandler)处理 I/O 事件,不需要手动轮询 Selector
AIO 适用于高并发、I/O 密集型场景,如聊天应用、大量连接的服务器。

  • 异步非阻塞:I/O 操作由操作系统完成,完成后触发回调函数(Callback)。
  • 线程资源消耗更低,不需要手动轮询 Selector

例:

AsynchronousServerSocketChannel server = AsynchronousServerSocketChannel.open();
server.bind(new InetSocketAddress(8080));

server.accept(null, new CompletionHandler<AsynchronousSocketChannel, Void>() {
    @Override
    public void completed(AsynchronousSocketChannel client, Void attachment) {
        server.accept(null, this); // 继续接受新连接
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        client.read(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() {
            @Override
            public void completed(Integer result, ByteBuffer buffer) {
                buffer.flip();
                client.write(buffer);
            }
            @Override
            public void failed(Throwable exc, ByteBuffer buffer) {
                exc.printStackTrace();
            }
        });
    }
    @Override
    public void failed(Throwable exc, Void attachment) {
        exc.printStackTrace();
    }
});
Thread.sleep(Long.MAX_VALUE); // 让主线程保持运行

技术选型:

  • BIO 适用于小型应用,如简单的 HTTP 服务器、普通 TCP 服务器。
  • NIO 适用于高并发场景,如 Web 服务器、聊天应用。
  • AIO 适用于超高并发场景,如海量连接的 IM 服务、视频直播系统。

如果你的项目需要支持大量并发连接(几千甚至几万连接),建议使用 NIO 或 AIO,而不是传统的 BIO。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值