JDK 7新特性非同期io/AIO
5647 ワード
概要
JDK 7はAsynchronous I/Oを導入した.I/Oプログラミングでは、ReactorとProactorの2つのモードによく使用されます.ReactorはJavaのNIOです.イベントがトリガーされると、通知を得て、対応する処理を行います.Proactorは私たちが今日お話しするAIOです.AIOはI/O操作を行い、いずれも非同期処理であり、イベントが完了すると通知されます.
JDK 7のAIOには、ネットワークおよびファイル操作が含まれる.両者は大きく異なり、aioのネットワーク操作を完全なクライアント/サーバSampleで詳細に説明します.
AIOは2つの非同期動作の傍受機構を提供した.1つ目は、Futureオブジェクトを返すことでイベントが発生し、get()を呼び出すと操作が完了するまで待機します.2つ目はコールバック関数に似ています.非同期操作を行うと、CompletionHandlerが渡され、非同期操作が終了するとCompletionHandler.completeインタフェースが呼び出されます.
例
この例の機能は、クライアントがサービス側に「test」コマンドを送信し、終了することです.
サービス・エンド・プログラムSever.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インタフェースには2つの方法があります
void completed(V result, A attachment);
void failed(Throwable exc, A attachment);
まとめ
本文はjdk 7のaio使用について簡単に説明しただけである.パフォーマンスの向上については、既存のネットワークアプリケーションをどのように改善するかを模索しています.ここでは、比較的成熟したネットワークフレームワークProject Grizzly:http://grizzly.dev.java.netをお勧めします.aioで再実現したそうですが、興味のある方はソースコードを検討してみてください.
参考資料
(以下、jdk 7のバージョンが低すぎて、多くのインタフェースが変更されています.慎重に!:)
http://www.ibm.com/developerworks/java/library/j-nio2-1/index.html?
http://www.iteye.com/topic/446298
http://www.iteye.com/topic/472333
本文はjdk 7シリーズの終わりで、皆さんの支持に感謝します!もっと多くの内容は私のブログにアクセスできます.
http://www.iamcoding.com