异步 I/O(AsynchronousChannel)
AIO(Asynchronous IO)是 Java 7 引入的真正异步 IO,操作完成后自动通知。
AIO vs NIO 非阻塞
| 特性 | NIO 非阻塞 | AIO 异步 |
|---|---|---|
| 调用方式 | read() 返回 0,需轮询 | read() 立即返回,完成后通知 |
| 处理方式 | 需要程序检查 | 系统完成,回调通知 |
| 线程模型 | Selector 线程轮询 | 系统线程完成,回调执行 |
AsynchronousFileChannel
Future 方式
Java
Path path = Paths.get("file.txt");
AsynchronousFileChannel channel = AsynchronousFileChannel.open(
path, StandardOpenOption.READ);
ByteBuffer buffer = ByteBuffer.allocate(1024);
Future<Integer> future = channel.read(buffer, 0); // 异步读取
// 等待完成(阻塞)
while (!future.isDone()) {
// 可做其他事情
}
int bytesRead = future.get(); // 获取结果
channel.close();
CompletionHandler 回调方式
Java
AsynchronousFileChannel channel = AsynchronousFileChannel.open(
path, StandardOpenOption.READ);
ByteBuffer buffer = ByteBuffer.allocate(1024);
channel.read(buffer, 0, null, new CompletionHandler<Integer, Void>() {
@Override
public void completed(Integer result, Void attachment) {
System.out.println("读取完成:" + result + " 字节");
}
@Override
public void failed(Throwable exc, Void attachment) {
System.out.println("读取失败:" + exc);
}
});
// 回调在其他线程执行,主线程可继续
Thread.sleep(1000); // 等待回调执行(示例)
channel.close();
异步写入
Java
AsynchronousFileChannel channel = AsynchronousFileChannel.open(
path, StandardOpenOption.WRITE);
ByteBuffer buffer = ByteBuffer.wrap("Hello".getBytes());
// Future 方式
Future<Integer> future = channel.write(buffer, 0);
future.get();
// 回调方式
channel.write(buffer, 0, null, new CompletionHandler<Integer, Void>() {
@Override
public void completed(Integer result, Void attachment) {
System.out.println("写入完成");
}
@Override
public void failed(Throwable exc, Void attachment) {
System.out.println("写入失败");
}
});
AsynchronousSocketChannel
异步客户端
Java
AsynchronousSocketChannel client = AsynchronousSocketChannel.open();
// 异步连接
Future<Void> connectFuture = client.connect(
new InetSocketAddress("localhost", 8080));
connectFuture.get(); // 等待连接完成
// 异步读取
ByteBuffer buffer = ByteBuffer.allocate(1024);
Future<Integer> readFuture = client.read(buffer);
int bytesRead = readFuture.get();
client.close();
回调方式
Java
AsynchronousSocketChannel client = AsynchronousSocketChannel.open();
client.connect(new InetSocketAddress("localhost", 8080), null,
new CompletionHandler<Void, Void>() {
@Override
public void completed(Void result, Void attachment) {
ByteBuffer buffer = ByteBuffer.allocate(1024);
client.read(buffer, null, new CompletionHandler<Integer, Void>() {
@Override
public void completed(Integer result, Void attachment) {
System.out.println("收到数据");
}
@Override
public void failed(Throwable exc, Void attachment) {
System.out.println("读取失败");
}
});
}
@Override
public void failed(Throwable exc, Void attachment) {
System.out.println("连接失败");
}
});
AsynchronousServerSocketChannel
异步服务端
Java
AsynchronousServerSocketChannel server = AsynchronousServerSocketChannel.open();
server.bind(new InetSocketAddress(8080));
server.accept(null, new CompletionHandler<AsynchronousSocketChannel, Void>() {
@Override
public void completed(AsynchronousSocketChannel client, Void attachment) {
// 继续接受下一个连接
server.accept(null, this);
// 处理当前客户端
ByteBuffer buffer = ByteBuffer.allocate(1024);
client.read(buffer, null, new CompletionHandler<Integer, Void>() {
@Override
public void completed(Integer result, Void attachment) {
buffer.flip();
client.write(buffer);
}
@Override
public void failed(Throwable exc, Void attachment) {
try { client.close(); } catch (Exception e) {}
}
});
}
@Override
public void failed(Throwable exc, Void attachment) {
System.out.println("accept 失败");
}
});
Thread.sleep(Long.MAX_VALUE); // 保持服务运行
Future vs CompletionHandler
| 方式 | 特点 | 适用场景 |
|---|---|---|
| Future | 需要手动等待或轮询 | 需要同步等待结果 |
| CompletionHandler | 完成后自动回调 | 真正异步,不阻塞 |
推荐回调方式:真正异步,不需要等待,适合高并发场景。
要点总结
- AIO 是真正的异步 IO,完成后自动通知
- Future 方式:调用后返回 Future,手动等待
- CompletionHandler 方式:完成后回调,真正异步
- AsynchronousFileChannel:异步文件操作
- AsynchronousSocketChannel:异步 TCP 客户端
- AsynchronousServerSocketChannel:异步 TCP 服务端
- 回调方式适合高并发,Future 方式适合需要同步等待
📝 发现内容有误?点击此处直接编辑