リニューアルされるソケットチャネル

ソケットチャネル機能は従来のNew I/Oにも実装されていたが、NIO.2ではこれが大幅にリニューアルされる予定だ。ソケットチャネルの機能を提供するjava.nio.channelsパッケージに対して大幅な修正が加えられる。主に以下のような点が変更されるという。

  • ネットワークに対するチャネルであるNetworkChannelインタフェースの追加
  • ソケットオプションの指定や取得、ローカルアドレスの取得などを行うメソッドの追加
  • マルチキャストをサポートするMulticastChannelインタフェースの追加
  • その他、各チャネルに対する細かな修正

この変更に伴って、従来から用意されていたSocketChannelやServerSocketChannelなどといったネットワーク関連のチャネルクラスもすべてNetworkChannelインタフェースをimplementsするようになるという。

マルチキャスト関連では、従来のDatagramChannelがMulticastChannelインタフェースをimplementsするようになる。また、後述する非同期通信をサポートしたAsynchronousDatagramChanelクラスも同様にMulticastChannelをimplementsするとのこと。

非同期入出力のサポート

NIO.2における3つ目のトピックが非同期入出力のサポートだ。NIO.2ではファイルとソケットの両方で非同期入出力がサポートされるという。非同期入出力のAPIには"Futureスタイル"と"Callbackスタイル"の2種類が用意される。前者はjava.util.concurrent.Futureオブジェクトを利用した方式であり、後者はハンドラを利用して入出力が終了した際の処理を記述する方式である。

まずFutureスタイルの例としてはリスト7のようなコードが紹介された。この例の場合、非同期接続や非同期入力の結果がFutureオブジェクトとして返されるので、それに対してget()メソッドを使用することで結果を取得することができる。

リスト7 Futureスタイルの例

AsynchronousSocketChannel ch = AcynchronousSocketChannel.open();

// 非同期接続の場合
Future result = ch.connect(remote);
result.get();

// 非同期入力の場合
ByteBuffer buf = ...
Future result = ch.read();

// 読み込みの完了待ち
try {
    int byteRead = result.get();
} catch() {
    ...
}

一方でCallbackスタイルはのようなコードになるという。CompletionHandlerインタフェースが非同期通信が終了した際に実行する処理を記述するためのハンドラである。IoFutureインタフェースはFutureのサブインタフェースで、非同期入出力操作に対する結果を表している。

リスト8 Callbackスタイルの例

AsynchronousSocketChannel ch = AsynchronousSocketChannel.open();

ch.read(buffer, new CompletionHandler() {
    public void completed(IoFuture result) {
        try {  
            int bytesRead = result.getNow();
               ...
        } catch (ExecutionException x) { 
               ...
        }
    }
});

NIO.2の非同期通信では、その他にタイムアウトの設定や非同期なクローズ処理、キャンセルなどの機能をサポートする予定との話である。

従来のNew I/O APIは、仕様を作ったエキスパートグループ自らが未完成のものだったと語っているようにあまり使い勝手のよいものとは言えず、それほど普及していないのが現状だ。その分、NIO.2に対する期待は大きく、実装されれば入出力関係のプログラミングモデルを大きく変えるだけのインパクトとなり得る。なお、NIO.2は仕様の策定と並行してOpenJDKのサブプロジェクトによって実装が進められている。