Java NIO 编程详解:缓冲区、通道与选择器的实际应用
·
Java NIO 核心组件概述
Java NIO(New I/O)通过非阻塞I/O模型提高高并发场景下的性能,核心组件包括:
- 缓冲区(Buffer):临时存储数据的容器,支持读写操作。
- 通道(Channel):连接数据源与缓冲区的双向数据传输管道。
- 选择器(Selector):监控多个通道的事件(如连接、读写),实现单线程多路复用。
缓冲区的使用
缓冲区通过ByteBuffer、CharBuffer等类实现,操作流程如下:
- 分配空间
ByteBuffer buffer = ByteBuffer.allocate(1024); // 分配堆内存 ByteBuffer directBuffer = ByteBuffer.allocateDirect(1024); // 直接内存(减少拷贝) - 写入数据
buffer.put("Hello".getBytes()); buffer.flip(); // 切换为读模式(limit=position, position=0) - 读取数据
while (buffer.hasRemaining()) { System.out.print((char) buffer.get()); } buffer.clear(); // 清空缓冲区(position=0, limit=capacity)
关键属性:
position:当前读写位置。limit:可操作数据边界。capacity:缓冲区容量。
通道的操作
通道通过FileChannel、SocketChannel等类实现数据传输。
文件通道示例:
try (FileChannel inChannel = FileChannel.open(Paths.get("input.txt"));
FileChannel outChannel = FileChannel.open(Paths.get("output.txt"),
StandardOpenOption.CREATE, StandardOpenOption.WRITE)) {
inChannel.transferTo(0, inChannel.size(), outChannel); // 零拷贝文件传输
}
网络通道示例:
SocketChannel socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false); // 非阻塞模式
socketChannel.connect(new InetSocketAddress("example.com", 80));
选择器的多路复用
选择器通过监听通道事件实现高并发处理。
注册与监听流程:
- 创建选择器
Selector selector = Selector.open(); - 注册通道事件
socketChannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_CONNECT); - 事件循环处理
while (true) { int readyChannels = selector.select(); // 阻塞直到事件就绪 Set<SelectionKey> keys = selector.selectedKeys(); for (SelectionKey key : keys) { if (key.isReadable()) { // 处理读事件 } keys.remove(key); } }
事件类型:
OP_READ:数据可读。OP_WRITE:数据可写。OP_CONNECT:连接就绪。OP_ACCEPT:服务端接受连接。
实际应用场景
- 高性能文件传输:结合
FileChannel.transferTo()实现零拷贝。 - 非阻塞网络通信:通过
Selector管理多个SocketChannel,减少线程开销。 - 自定义协议解析:使用
ByteBuffer灵活处理二进制数据。
注意事项:
- 直接内存缓冲区(
allocateDirect)适合高频I/O操作,但分配成本较高。 - 非阻塞模式下需处理未完成连接(
finishConnect())。 - 选择器的
selectedKeys集合需手动移除已处理键。
更多推荐


所有评论(0)