Java的AIO

Java的AIO教程

AIO 全程 Asynchronous I/O,它是异步的,客户端发起请求之后不需要等待服务端响应可以做其他的事情,然后服务端业务逻辑处理完之后会将处理结果通知客户端。客户端这个时候会到指定的缓冲区获取数据。

Java的AIO描述

与 NIO 不同的地方在于,Channel 对应的接口是异步的,主要涉及到的类:AsynchronousServerSocketChannel(服务器接收请求通道)、AsynchronousSocketChannel(Socket 通讯通道)、CompletionHandler(异步处理类)。

案例

AioServer

package net.haicoder.server; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.AsynchronousChannelGroup; import java.nio.channels.AsynchronousServerSocketChannel; import java.nio.channels.AsynchronousSocketChannel; import java.nio.channels.CompletionHandler; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class AioServer { private final int port; public static void main(String[] args) { int port = 9999; new AioServer(port); } public AioServer(int port) { this.port = port; listen(); while (true) { try { Thread.sleep(1000000); } catch (InterruptedException e) { } } } private void listen() { try { ExecutorService executorService = Executors.newCachedThreadPool(); AsynchronousChannelGroup threadGroup = AsynchronousChannelGroup.withCachedThreadPool(executorService, 1); final AsynchronousServerSocketChannel serverSocketChannel = AsynchronousServerSocketChannel.open(threadGroup); serverSocketChannel.bind(new InetSocketAddress(port)); System.out.println("服务已经启动,监听端口:" + port); serverSocketChannel.accept(null, new CompletionHandler<AsynchronousSocketChannel, Object>() { final ByteBuffer byteBuffer = ByteBuffer.allocate(1024); @Override public void completed(AsynchronousSocketChannel result, Object attachment) { System.out.println("I/O 操作成功,开始获取数据"); try { byteBuffer.clear(); result.read(byteBuffer).get(); byteBuffer.flip(); System.out.println("服务端接收到数据:" + new String(byteBuffer.array()).trim()); result.write(byteBuffer); byteBuffer.flip(); } catch (Exception e) { e.printStackTrace(); } finally { try { result.close(); serverSocketChannel.accept(null, this); } catch (Exception e) { e.printStackTrace(); } } System.out.println("操作完成"); } @Override public void failed(Throwable exc, Object attachment) { System.out.println("I/O 操作失败:" + exc); } }); Thread.sleep(1000); } catch (Exception e) { e.printStackTrace(); } } }

AioClient

package net.haicoder.client; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.AsynchronousSocketChannel; import java.nio.channels.CompletionHandler; public class AioClient { private AsynchronousSocketChannel clientChannel; private static final String host = "127.0.0.1"; private static final Integer port = 9999; public AioClient() throws Exception { clientChannel = AsynchronousSocketChannel.open(); } public void connect(String host, int port) { try { clientChannel.connect(new InetSocketAddress(host, port), null, new CompletionHandler<Void, Void>() { @Override public void completed(Void result, Void attachment) { try { clientChannel.write(ByteBuffer.wrap("你好嗨客网,客户端链接成功了".getBytes())).get(); System.out.println("数据已经发送成功!"); } catch (Exception e) { e.printStackTrace(); } } @Override public void failed(Throwable exc, Void attachment) { } }); } catch (Exception e) { e.printStackTrace(); } try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } // 定义一个ByteBuffer准备读取数据 final ByteBuffer byteBuffer = ByteBuffer.allocate(1024); clientChannel.read(byteBuffer, null, new CompletionHandler<Integer, Object>() { @Override public void completed(Integer result, Object attachment) { System.out.println("I/O操作完成" + result); System.out.println("获取返回结果:" + new String(byteBuffer.array()).trim()); } @Override public void failed(Throwable exc, Object attachment) { exc.printStackTrace(); } }); } public static void main(String[] args) throws Exception { AioClient aioClient = new AioClient(); aioClient.connect(host, port); } }

运行结果如下:

14 aio 运行结果.png

在项目测试的时候,和前面的 IO 一样,也是需要先启动服务端,然后再启动客户端。

AIO总结

AIO 是完全异步非阻塞的模型,当客户端向服务端发起请求之后,客户端不需要等待也不需要轮询结果,服务端执行完之后会通知客户端让客户端进行处理。

主要涉及到的类:AsynchronousServerSocketChannel(服务器接收请求通道)、AsynchronousSocketChannel(Socket 通讯通道)、CompletionHandler(异步处理类)。