概述
JDK7引入了Asynchronous I/O。I/O編程中,經常使用到兩種模式:Reactor 和 Proactor。Reactor就是Java的NIO。當有事件觸發時,咱們獲得通知,進行相應的處理。Proactor就是咱們今天要講的 AIO了。AIO進行I/O操做,都是異步處理,當事件完成時,咱們會獲得通知。
JDK7的 AIO包括網絡和文件操做。二者大同小異,本文經過一個完整的客戶端/服務器Sample來詳細說明aio的網絡操做。
AIO提供了兩種異步操做的監聽機制。第一種經過返回一個Future對象來事件,調用其get()會等到操做完成。第二種相似於回調函數。在進行異步操做時,傳遞一個CompletionHandler,當異步操做結束時,會調用CompletionHandler.complete 接口 html
範例
這個範例功能比較簡單,就是客戶端向服務端發送一個「test」命令,而後結束。
服務端程序 Sever.java
Java代碼: java
import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.AsynchronousServerSocketChannel; import java.nio.channels.AsynchronousSocketChannel; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; public class Server { private AsynchronousServerSocketChannel server; public Server()throws IOException{ server = AsynchronousServerSocketChannel.open().bind(new InetSocketAddress(8888)); } public void start() throws InterruptedException, ExecutionException, TimeoutException{ Future<AsynchronousSocketChannel> future = server.accept(); AsynchronousSocketChannel socket = future.get(); ByteBuffer readBuf = ByteBuffer.allocate(1024); socket.read(readBuf).get(100, TimeUnit.SECONDS); System.out.printf("Receiver:%s%n",new String(readBuf.array())); } public static void main(String args[]) throws Exception{ new Server().start(); } }客戶端程序 (Future版本)
import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.AsynchronousSocketChannel; import java.util.concurrent.ExecutionException; public class AIOClientWithFuture { private final AsynchronousSocketChannel client; public AIOClientWithFuture() throws IOException{ client = AsynchronousSocketChannel.open(); } public void sendMsg() throws InterruptedException, ExecutionException{ client.connect(new InetSocketAddress("localhost",8888)); client.write(ByteBuffer.wrap("test".getBytes())).get(); } public static void main(String...args) throws Exception{ AIOClientWithFuture client = new AIOClientWithFuture(); client.sendMsg(); } }客戶端程序(CompleteHandler版本)
import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.AsynchronousSocketChannel; import java.nio.channels.CompletionHandler; public class AIOClientWithHandler { private final AsynchronousSocketChannel client ; public AIOClientWithHandler() throws Exception{ client = AsynchronousSocketChannel.open(); } public void start()throws Exception{ client.connect(new InetSocketAddress("127.0.0.1",8888),null,new CompletionHandler<Void,Void>() { @Override public void completed(Void result, Void attachment) { try { client.write(ByteBuffer.wrap("test".getBytes())).get(); } catch (Exception ex) { ex.printStackTrace(); } } @Override public void failed(Throwable exc, Void attachment) { exc.printStackTrace(); } }); } public static void main(String args[])throws Exception{ new AIOClientWithHandler().start(); } }
相關類說明:
AsynchronousSocketChannel 跟 SocketChannel操做相似,只不過改爲異步接口了
AsynchronousServerSocketChannel跟ServerSocketChannel操做相似,只不過改爲異步接口了
CompletionHandler 接口包括兩個方法
void completed(V result, A attachment);
void failed(Throwable exc, A attachment); 編程
總結:
本文只是對jdk7的aio使用作了一個簡單的說明。至於其性能提高多少,如何改進現有的網絡應用程序,還在摸索中。這裏推薦一個比較成熟的網絡框架Project Grizzly:http://grizzly.dev.java.net。聽說已經用aio從新實現了,有興趣的同窗能夠去研究一下源碼。 服務器
參考資料:
(如下有些資料使用的jdk7版本過低,不少接口已經更改了,慎入!:) 網絡
http://www.ibm.com/developerworks/java/library/j-nio2-1/index.html? 框架
http://www.iteye.com/topic/446298 異步
http://www.iteye.com/topic/472333 socket