Java-AIO
概述
Asynchronous IO也称为AIO,即异步⾮阻塞IO。Java7提供了改进版的NIO,引⼊了异步⾮阻塞的IO,由操作系统完成后回调通知服务端程序启动线程去处理。⼀般适⽤于连接数较多且连接时间较⻓的应⽤。
实现
-
服务端实现
package com.my.io.aio; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.AsynchronousServerSocketChannel; import java.nio.channels.AsynchronousSocketChannel; import java.nio.channels.CompletionHandler; /** * @author zhupanlin * @version 1.0 * @description: AIO Socket的服务端 * @date 2024/1/27 12:45 */ public class AIOServer { public static void main(String[] args) throws IOException, InterruptedException { // 获得异步的Server Socket Channel AsynchronousServerSocketChannel serverSocketChannel = AsynchronousServerSocketChannel.open(); // 绑定端口 serverSocketChannel.bind(new InetSocketAddress(9001)); // 异步接收 serverSocketChannel.accept(null, new CompletionHandler<AsynchronousSocketChannel, Object>() { /** * 当有连接时调用的方法 * @param socketChannel * The result of the I/O operation. * @param attachment * The object attached to the I/O operation when it was initiated. */ @Override public void completed(AsynchronousSocketChannel socketChannel, Object attachment) { try { // 开始处理连接,建立连接的通道 serverSocketChannel.accept(attachment, this); System.out.println("客户端:" + socketChannel.getRemoteAddress()); // 创建buffer ByteBuffer buffer = ByteBuffer.allocate(1024); // 异步的读客户端的数据 socketChannel.read(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() { /** * 当客户端写数据时调用 * @param result * The result of the I/O operation. * @param byteBuffer * The object attached to the I/O operation when it was initiated. */ @Override public void completed(Integer result, ByteBuffer byteBuffer) { byteBuffer.flip(); System.out.println("客户端发的消息:" + new String(byteBuffer.array(), 0, result)); // 向客户端返回消息 socketChannel.write(ByteBuffer.wrap("hello asynchronousChannelClient".getBytes())); } @Override public void failed(Throwable exc, ByteBuffer attachment) { } }); } catch (IOException e) { throw new RuntimeException(e); } } /** * 当连接失败时调用的方法 * @param exc * The exception to indicate why the I/O operation failed * @param attachment * The object attached to the I/O operation when it was initiated. */ @Override public void failed(Throwable exc, Object attachment) { } }); // 体会异步的特点,如果没有延时,主线程会直接结束 System.out.println("main thread..."); Thread.sleep(10000); } }
-
客户端实现
package com.my.io.aio; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.AsynchronousSocketChannel; import java.util.concurrent.ExecutionException; /** * @author zhupanlin * @version 1.0 * @description: AIO的客户端 * @date 2024/1/27 16:20 */ public class AIOClient { public static void main(String[] args) throws IOException, ExecutionException, InterruptedException { // 获得异步的SocketChannel AsynchronousSocketChannel socketChannel = AsynchronousSocketChannel.open(); // 连接服务器,让连接的异步动作变成同步的 socketChannel.connect(new InetSocketAddress("localhost", 9001)).get(); // 发送数据 socketChannel.write(ByteBuffer.wrap("hello asynchronousChannelServer".getBytes())); // 获得返回的数据 ByteBuffer buffer = ByteBuffer.allocate(1024); int len = 0; while ((len = socketChannel.read(buffer).get()) > 0){ System.out.println("服务端返回的消息:" + new String(buffer.array(), 0, len)); } } }
BIO、NIO、AIO对比
BIO | NIO | AIO | |
---|---|---|---|
IO模型 | 同步阻塞 | 同步非阻塞 | 异步非阻塞 |
编程难度 | 简单 | 复杂 | 复杂 |
可靠性 | 差 | 好 | 好 |
吞吐量 | 低 | 高 | 高 |