Skip to content

Java NIO 入门指南

什么是Java NIO?

Java NIO(Non-blocking IO)是一种基于事件驱动的I/O技术,旨在提高高并发场景下的系统性能。相比传统的阻塞I/O模型,NIO通过更高效的方式来处理多个连接。


核心组件

  1. Channel

    • 类似于传统IO中的Stream,用于实际数据传输。
    • 常见类型:
      • FileChannel:文件操作。
      • SocketChannel:网络通信(TCP)。
      • DatagramChannel:无连接的UDP通信。
  2. Buffer

    • 数据存储容器,支持高效的数据读写操作。
    • 常见类型:
      • ByteBuffer
      • CharBuffer
  3. Selector

    • 用于注册和监听多个Channel的I/O事件。
    • 当某个Channel准备好进行读/写时,Selector会通知应用程序。

NIO的优点

  • 使用一个线程即可处理大量连接(非阻塞模式)。
  • 节省资源:相比传统的多线程模型,NIO减少了线程数量和系统开销。

示例代码

1. 创建ServerSocketChannel并绑定端口
java
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;

public class NIOServer {
    public static void main(String[] args) throws Exception {
        ServerSocketChannel server = ServerSocketChannel.open();
        server.bind(new InetSocketAddress("localhost", 8080));
        
        while (true) {
            SocketChannel client = server.accept(); // 阻塞,直到有新连接
            System.out.println("New client connected");
            
            new Thread(() -> {
                try {
                    while (true) {
                        ByteBuffer buffer = ByteBuffer.allocate(1024);
                        int bytesRead = client.read(buffer);
                        
                        if (bytesRead == -1) { // 连接关闭
                            break;
                        }
                        
                        String message = new String(buffer.array(), 0, bytesRead).trim();
                        System.out.println("Received: " + message);
                        
                        buffer.flip(); // 准备写数据
                        client.write(buffer); // 发送响应
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
}
2. 创建SocketChannel并连接服务器
java
import java.nio.channels.SocketChannel;

public class NIOClient {
    public static void main(String[] args) throws Exception {
        SocketChannel client = SocketChannel.open(new InetSocketAddress("localhost", 8080));
        
        ByteBuffer buffer = ByteBuffer.wrap("Hello, Server!".getBytes());
        buffer.flip();
        
        System.out.println("Sending: Hello, Server!");
        int bytesWritten = client.write(buffer);
        
        // 等待服务器响应
        Thread.sleep(1000);
    }
}

运行步骤

  1. 启动 NIOServer,它会在8080端口监听连接。
  2. 启动 NIOClient,发送数据到服务器。

运行后:

  • 服务端会打印出“New client connected”和接收到的消息。
  • 客户端会显示已成功发送消息,并等待响应。

总结

通过上述代码示例可以看出,Java NIO在处理高并发场景时更加高效。它允许用更少的线程管理更多的连接,从而降低了系统资源消耗。