DEV Community

Woody
Woody

Posted on

about BIO NIO AIO AND Netty

下面是一篇关于 Java 网络编程模型(BIO、NIO、AIO)以及 Netty 中阻塞/非阻塞、同步/异步模型 的系统教程,适合有一定 Java 基础的开发者阅读。


Java 网络编程模型:BIO、NIO、AIO 与 Netty 的阻塞/非阻塞、同步/异步机制详解

在网络编程中,高并发和低延迟是开发者追求的核心目标。Java 提供了多种 I/O 模型来满足不同场景下的需求,包括 BIO、NIO 和 AIO。此外,Netty 作为高性能网络通信框架,对这些模型进行了封装和优化。

本文将系统介绍:

  • BIO / NIO / AIO 的原理与区别
  • 阻塞 / 非阻塞、同步 / 异步的概念
  • Netty 是如何实现高性能的

一、关键概念速览

1. 阻塞 vs 非阻塞

  • 阻塞(Blocking):调用方在等待操作完成时会停留在当前线程,无法做其他事。
  • 非阻塞(Non-blocking):调用方发出请求后立即返回,可以继续执行其他任务。

2. 同步 vs 异步

  • 同步(Synchronous):调用发出后,自己等待结果(不管是阻塞还是轮询)。
  • 异步(Asynchronous):调用发出后,不等待结果,结果通过回调、通知等机制返回。
模式 是否阻塞线程 是否主动等待结果 示例
阻塞同步 BIO
非阻塞同步 NIO
异步非阻塞 AIO、Netty

二、BIO(Blocking I/O)

特点

  • 基于线程阻塞的传统 I/O 模型。
  • 每个客户端连接一个线程。
  • 适合连接数少、任务简单的场景。

示例代码

ServerSocket serverSocket = new ServerSocket(8080);
while (true) {
    Socket socket = serverSocket.accept(); // 阻塞
    new Thread(() -> {
        InputStream in = socket.getInputStream(); // 阻塞
        ...
    }).start();
}
Enter fullscreen mode Exit fullscreen mode

缺点

  • 并发性差:每个请求都需要线程处理,线程资源开销大。
  • 容易造成线程资源耗尽。

三、NIO(Non-blocking I/O)

特点

  • 单线程管理多个连接(基于 Selector)。
  • 非阻塞模式:Channel 可以在没有数据时返回。
  • 本质是非阻塞同步

核心组件

  • Channel:双向通道(代替 Socket)
  • Buffer:数据容器
  • Selector:多路复用器

示例代码

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

while (true) {
    selector.select(); // 阻塞直到有事件
    Set<SelectionKey> keys = selector.selectedKeys();
    ...
}
Enter fullscreen mode Exit fullscreen mode

优势

  • 单线程处理多连接,极大提高资源利用率。
  • 可构建高性能服务器。

四、AIO(Asynchronous I/O)

特点

  • 完全异步,基于操作系统底层支持。
  • 发起调用后立即返回,由操作系统完成后回调通知。

示例代码(Java 7+)

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

server.accept(null, new CompletionHandler<AsynchronousSocketChannel, Void>() {
    public void completed(AsynchronousSocketChannel channel, Void att) {
        // 连接完成,继续 accept
        server.accept(null, this);
        // 处理读写
    }
    public void failed(Throwable exc, Void att) {}
});
Enter fullscreen mode Exit fullscreen mode

优势与限制

  • 真正意义上的异步非阻塞。
  • 编程复杂度较高,依赖底层 OS 的支持程度。

五、Netty 框架:高性能异步网络通信

简介

Netty 是基于 NIO 的高性能网络通信框架,广泛应用于分布式系统(如 Dubbo、Elasticsearch)。

特点

  • 封装了复杂的 NIO 编程
  • 支持多种协议(TCP、UDP、HTTP 等)
  • 内部线程模型灵活、高效

Netty 的异步模型

  • 默认基于 Reactor 模式,支持单线程(单 Reactor)和多线程(多 Reactor)模型。
  • 采用事件驱动(EventLoop),本质上是 非阻塞 + 异步 + 多线程分工协作

示例代码

EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();

ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
 .channel(NioServerSocketChannel.class)
 .childHandler(new ChannelInitializer<SocketChannel>() {
     @Override
     public void initChannel(SocketChannel ch) {
         ch.pipeline().addLast(new MyHandler());
     }
});
b.bind(8080).sync();
Enter fullscreen mode Exit fullscreen mode

为什么 Netty 异步?

  • 所有操作(连接、读写)都返回 ChannelFuture,通过监听器方式通知是否完成。
  • 通过事件触发机制完成异步响应。

六、总结:选择哪种模型?

场景 建议模型 理由
简单项目、小流量网站 BIO 编程简单,易于调试
高并发、长连接系统 NIO 或 Netty 更少线程处理更多连接,提高吞吐量和性能
低延迟异步服务 AIO 或 Netty 真正异步响应,系统资源利用率更高

七、图示对比(可视化思维)

BIO:
    [Client]--->[Thread-1 Blocking Read]
    [Client]--->[Thread-2 Blocking Read]

NIO:
    [Selector]
        |
    [Thread] handles many channels
        |
    [Client-1] [Client-2] [Client-N]

AIO:
    [Client]--->OS handles IO--->Callback
Enter fullscreen mode Exit fullscreen mode

如果你希望进一步了解 Netty 的线程模型、管道机制、心跳检测、粘包拆包等内容,可以继续深入学习 Netty 的源码或使用场景实践。

如需我为你生成 Netty 项目模板或 NIO 样例代码,也可以告诉我。


Top comments (0)