







Java / 后端开发中核心的 IO 模型分类,是网络编程、高并发开发的基础知识点。主流的 IO 模型分为5 类(从最基础的阻塞 IO 到高性能的异步 IO),本文用通俗易懂的语言从浅到深讲解,结合场景和比喻快速理解。
先明确核心概念:IO 操作的本质是「数据从内核缓冲区到用户缓冲区」的拷贝过程,IO 模型的差异体现在等待数据阶段和拷贝数据阶段的阻塞 / 非阻塞特性。
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
// BIO服务端:一个连接对应一个线程,线程全程阻塞等待数据
public class BIOExample {
public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(8080);
System.out.println("BIO服务端启动,等待连接...");
while (true) {
// 阻塞:等待客户端连接
Socket socket = serverSocket.accept();
// 新建线程处理该连接(否则无法接收下一个连接)
new Thread(() -> {
try {
InputStream in = socket.getInputStream();
byte[] buf = new byte[1024];
// 阻塞:等待数据并拷贝到用户缓冲区
int len = in.read(buf);
if (len > 0) {
System.out.println("收到数据:" + new String(buf, 0, len));
}
in.close();
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
}
}
select/poll/epoll、Java 的Selector),一个线程可以监听多个 IO 通道:import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
// NIO多路复用核心逻辑
public class NIOSelectorExample {
public static void main(String[] args) throws Exception {
// 1. 创建多路复用器(Selector)
Selector selector = Selector.open();
// 2. 创建服务端通道并注册到Selector
ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.bind(new java.net.InetSocketAddress(8080));
serverChannel.configureBlocking(false); // 设置为非阻塞
serverChannel.register(selector, java.nio.channels.SelectionKey.OP_ACCEPT);
while (true) {
// 3. 阻塞:等待有就绪的IO事件(连接/数据可读)
selector.select();
// 4. 遍历所有就绪的事件并处理
for (java.nio.channels.SelectionKey key : selector.selectedKeys()) {
if (key.isAcceptable()) {
// 处理新连接
SocketChannel clientChannel = ((ServerSocketChannel) key.channel()).accept();
clientChannel.configureBlocking(false);
// 注册读事件
clientChannel.register(selector, java.nio.channels.SelectionKey.OP_READ);
} else if (key.isReadable()) {
// 处理数据读取(拷贝阶段仍阻塞,但仅针对就绪的通道)
SocketChannel clientChannel = (SocketChannel) key.channel();
java.nio.ByteBuffer buf = java.nio.ByteBuffer.allocate(1024);
int len = clientChannel.read(buf);
if (len > 0) {
System.out.println("收到数据:" + new String(buf.array(), 0, len));
}
clientChannel.close();
}
}
selector.selectedKeys().clear(); // 清空已处理的事件
}
}
}
select/poll(轮询所有注册通道)效率低于epoll(事件通知机制),Java NIO 在 Linux 下默认用 epoll。SIGIO信号,应用程序收到信号后,再发起 IO 调用(拷贝数据阶段阻塞)。import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
// AIO服务端:异步处理连接和数据读取
public class AIOExample {
public static void main(String[] args) throws Exception {
// 1. 创建异步服务端通道
AsynchronousServerSocketChannel serverChannel = AsynchronousServerSocketChannel.open();
serverChannel.bind(new InetSocketAddress(8080));
System.out.println("AIO服务端启动,等待连接...");
// 2. 异步接受连接(非阻塞,完成后回调)
serverChannel.accept(null, new CompletionHandler<AsynchronousSocketChannel, Object>() {
@Override
public void completed(AsynchronousSocketChannel clientChannel, Object attachment) {
// 继续接受下一个连接(否则只能处理一个连接)
serverChannel.accept(null, this);
// 3. 异步读取数据(完成后回调)
ByteBuffer buf = ByteBuffer.allocate(1024);
clientChannel.read(buf, buf, new CompletionHandler<Integer, ByteBuffer>() {
@Override
public void completed(Integer len, ByteBuffer buffer) {
if (len > 0) {
buffer.flip();
System.out.println("收到数据:" + new String(buffer.array(), 0, len));
}
try {
clientChannel.close();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void failed(Throwable exc, ByteBuffer buffer) {
exc.printStackTrace();
}
});
}
@Override
public void failed(Throwable exc, Object attachment) {
exc.printStackTrace();
}
});
// 主线程不退出
Thread.sleep(Integer.MAX_VALUE);
}
}
| IO 模型 | 等待数据阶段 | 拷贝数据阶段 | 核心特点 | Java 实现 |
|---|---|---|---|---|
| 阻塞 IO(BIO) | 阻塞 | 阻塞 | 简单但性能差 | Socket、ServerSocket |
| 非阻塞 IO(NIO) | 非阻塞(轮询) | 阻塞 | 减少等待,但 CPU 开销大 | Java NIO(非 Selector) |
| IO 多路复用 | 阻塞(复用器) | 阻塞 | 一个线程管理多通道,高效 | Java NIO Selector |
| 信号驱动 IO | 非阻塞(信号) | 阻塞 | 无需轮询,实现复杂 | 无直接 Java API |
| 异步 IO(AIO) | 非阻塞 | 非阻塞 | 全异步,性能最高 | Java NIO.2(AIO) |
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。