AIO中的A即Asynchronous,AIO即異步IO。它是異步非阻塞的,客戶端的I/O請求都是由OS先完成了再通知服務器應用去啓動線程進行處理,通常咱們的業務處理邏輯會變成一個回調函數,等待IO操做完成後,由系統自動觸發。vue
在進行讀寫操做時,只需直接調用API的read/write方法便可。這兩種方法均爲異步的,對於讀操做而言,當有流可讀取時,操做系統會將可讀的流傳入read方法的緩衝區,並通知應用程序;對於寫操做而言,當操做系統將write方法傳遞的流寫入完畢時,操做系統主動通知應用程序。便可以理解爲,read/write方法都是異步的,完成後會主動調用回調函數。c++
AIO實際上是對NIO的加強,新增了許多支持異步的類如AsynchronousServerSocketChannel,AsynchronousChannel,AsynchronousChannelGroup,CompletionHandler等。windows
在Linux系統中AIO和NIO的底層實現都是epoll,epoll自己是輪詢模型,AIO只不過是對epoll又包了一層,而在windows系統中AIO是經過IOCP(完成端口)實現。而目前大多數的服務器都是Linux系統,這也是Netty中使用NIO而非AIO的一個緣由,在實際使用中因爲操做系統的差別,AIO的性能有時並無NIO高效,所以AIO的使用並無很普遍。服務器
AIO服務端代碼示例:markdown
public class AIOServer { public static void main(String[] args) throws IOException { // 多線程版本 // ExecutorService executorService = Executors.newCachedThreadPool(); // AsynchronousChannelGroup channelGroup = // AsynchronousChannelGroup.withCachedThreadPool(executorService, 1); // AsynchronousServerSocketChannel serverSocketChannel = // AsynchronousServerSocketChannel.open(channelGroup).bind(new // InetSocketAddress(8080)); // 單線程版本 AsynchronousServerSocketChannel serverSocketChannel = AsynchronousServerSocketChannel.open().bind(new InetSocketAddress(8080)); serverSocketChannel.accept( null, new CompletionHandler<AsynchronousSocketChannel, Object>() { @Override public void completed(AsynchronousSocketChannel client, Object attachment) { serverSocketChannel.accept(null, this); try { System.out.println(client.getRemoteAddress()); ByteBuffer byteBuffer = ByteBuffer.allocate(1024); client.read( byteBuffer, byteBuffer, new CompletionHandler<Integer, ByteBuffer>() { @Override public void completed(Integer result, ByteBuffer attachment) { attachment.flip(); byte[] content = new byte[attachment.limit()]; attachment.get(content); System.out.println(new String(content)); try { System.out.println("Client: " + client.getRemoteAddress()); } catch (IOException e) { e.printStackTrace(); } } @Override public void failed(Throwable exc, ByteBuffer attachment) { System.out.println("failed: " + exc.getMessage()); } }); } catch (Exception e) { e.printStackTrace(); } } @Override public void failed(Throwable exc, Object attachment) {} }); while (true) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }
AIO客戶端代碼示例:多線程
public class AIOClient { public static void main(String[] args) throws Exception { AsynchronousSocketChannel socketChannel = AsynchronousSocketChannel.open(); socketChannel.connect(new InetSocketAddress("127.0.0.1", 8080)); Thread.sleep(1000); ByteBuffer buffer = ByteBuffer.wrap("Hello Server".getBytes()); socketChannel.write(buffer).get(); } }