Java NIO 模型笔记

发布于:2025-07-07 ⋅ 阅读:(24) ⋅ 点赞:(0)

目录

  1. Java NIO 概述

  2. Java BIO vs NIO

  3. NIO 三大核心组件

    • Channel(通道)
    • Buffer(缓冲区)
    • Selector(选择器)
  4. Channel 详解

  5. Buffer 详解

  6. Selector 详解

  7. NIO 工作流程图

  8. 示例代码讲解

  9. NIO 模型的优缺点

  10. NIO 与 Netty 简介

  11. 总结


Java NIO 概述

Java NIO(New I/O)是从 Java 1.4 开始引入的一套新的 I/O API。主要用于 构建高性能、高并发的网络通信程序

特点

  • 面向缓冲区(Buffer)而不是面向流(Stream)
  • 支持非阻塞模式(Non-blocking)
  • 使用选择器(Selector)实现多路复用
  • 更适合高并发服务器端开发

Java BIO vs NIO

特性 BIO(传统 I/O) NIO(新 I/O)
处理方式 同步阻塞 同步非阻塞
数据处理 面向流 面向缓冲区
多路复用 不支持 支持
并发模型 一个线程处理一个连接 一个线程处理多个连接
适用场景 连接数较少,简单 高并发、高性能服务器

NIO 三大核心组件

1. Channel(通道)

双向的数据传输通道。可以读、写或者同时读写。

常见 Channel 类型:

  • FileChannel:用于文件数据的读写
  • SocketChannel:用于 TCP 网络通信
  • ServerSocketChannel:用于 TCP 服务端连接监听
  • DatagramChannel:用于 UDP 数据通信

2. Buffer(缓冲区)

用于存储读取/写入的数据,是 NIO 数据处理的核心。

常见缓冲区类型:

  • ByteBuffer
  • CharBuffer
  • IntBuffer
  • FloatBuffer
  • LongBuffer

3. Selector(选择器)

用于监听多个 Channel 的事件(如连接、读取、写入),实现 单线程处理多个连接 的能力。


Channel 详解

Channel 是数据的载体,可以与 Buffer 进行读写操作。

// 创建一个 ServerSocketChannel
ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.bind(new InetSocketAddress(8080));
serverChannel.configureBlocking(false); // 设置非阻塞

Channel 支持以下操作:

  • read(Buffer buffer)
  • write(Buffer buffer)
  • register(Selector selector, int ops) 注册监听事件

Buffer 详解

主要属性:

  • position:当前操作位置
  • limit:限制(最多能操作到哪里)
  • capacity:容量(最大能装多少数据)

常用方法:

  • put() / get():写入/读取
  • flip():读写模式切换
  • clear():清空缓冲区
  • rewind():重置 position 为 0
ByteBuffer buffer = ByteBuffer.allocate(1024);
buffer.put("hello".getBytes());
buffer.flip();
byte[] data = new byte[buffer.remaining()];
buffer.get(data);

Selector 详解

Selector 是 Java NIO 提供的 事件轮询器,用于监听多个 Channel 的事件。

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

事件类型:

事件 描述
OP_ACCEPT 接收连接请求
OP_CONNECT 完成连接
OP_READ 可读取数据
OP_WRITE 可写入数据

Selector 处理流程:

  1. 调用 selector.select() 阻塞等待事件
  2. 获取 selectedKeys()
  3. 遍历处理每个事件(如接收连接、读取数据等)

NIO 工作流程图

      +-------------+              +------------------+
      | Client      |              | Server           |
      +-------------+              +------------------+
             |                              |
             |        TCP Connect           |
             |----------------------------->|
             |                              |
             |                              |
             |<-----------------------------|
             |   Register Channel to Selector
             |                              |
             |---> OP_READ / OP_WRITE ----->|
             |                              |
             |<--- selector.select() -------|
             |                              |
             |<-------- Read/Write -------->|

示例代码讲解

服务端代码

ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.configureBlocking(false);
serverChannel.bind(new InetSocketAddress(9999));

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

while (true) {
    selector.select();
    Set<SelectionKey> keys = selector.selectedKeys();
    Iterator<SelectionKey> iter = keys.iterator();

    while (iter.hasNext()) {
        SelectionKey key = iter.next();
        iter.remove();

        if (key.isAcceptable()) {
            SocketChannel client = serverChannel.accept();
            client.configureBlocking(false);
            client.register(selector, SelectionKey.OP_READ);
        }

        if (key.isReadable()) {
            SocketChannel client = (SocketChannel) key.channel();
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            int read = client.read(buffer);
            if (read > 0) {
                buffer.flip();
                System.out.println("Received: " + new String(buffer.array(), 0, read));
            }
        }
    }
}

NIO 模型的优缺点

优点

  • 更适合构建高并发服务器
  • 非阻塞方式提升资源利用率
  • 支持多路复用减少线程数量

缺点

  • 编程复杂度较高
  • 不是真正的异步(NIO 是同步非阻塞)
  • 调试和维护成本高于 BIO

NIO 与 Netty 简介

Netty 是基于 Java NIO 封装的高性能网络通信框架。

Netty 优点:

  • 封装了复杂的 NIO 使用细节
  • 提供异步、事件驱动模型
  • 内建线程池、内存管理机制
  • 广泛应用于高性能服务器(如 Dubbo、Elasticsearch)

总结

  • Java NIO 是面向缓冲区的非阻塞 I/O 模型。
  • 三大核心组件:Channel、Buffer、Selector。
  • NIO 更适合高并发场景,但开发复杂度较高。
  • 实际开发中建议使用 Netty 等高层封装框架。

网站公告

今日签到

点亮在社区的每一天
去签到