JavaNIO-セレクター

Java NIOは、チャネルとバッファとの間の複数のトランザクションをサポートしていることがわかっています。したがって、1つ以上のNIOチャネルを調べて、データトランザクションの準備ができているチャネルを判別するために、JavaNIOはセレクタを提供します。

Selectorを使用すると、どのチャネルがデータの書き込みと読み取りの準備ができているかを知るためのスレッドを作成し、その特定のチャネルを処理できます。

静的メソッドを呼び出すことでセレクターインスタンスを取得できます open()セレクターを開いた後、SelectionKeyのインスタンスを返す非ブロッキングモードチャネルを登録する必要があります。

SelectionKeyは基本的に、チャネルで実行できる操作のコレクションです。または、選択キーを使用してチャネルの状態を知ることができたと言えます。

選択キーで表される主な操作またはチャネルの状態は次のとおりです。

  • SelectionKey.OP_CONNECT −サーバーに接続する準備ができているチャネル。

  • SelectionKey.OP_ACCEPT −着信接続を受け入れる準備ができているチャネル。

  • SelectionKey.OP_READ −データ読み取りの準備ができているチャネル。

  • SelectionKey.OP_WRITE −データ書き込みの準備ができているチャネル。

登録後に取得した選択キーには、以下のような重要な方法があります。

  • attach() −この方法は、キーを使用してオブジェクトをアタッチするために使用されます。オブジェクトをチャネルにアタッチする主な目的は、同じチャネルを認識することです。

  • attachment() −このメソッドは、チャネルからアタッチされたオブジェクトを保持するために使用されます。

  • channel() −このメソッドは、特定のキーが作成されるチャネルを取得するために使用されます。

  • selector() −このメソッドは、特定のキーが作成されるセレクターを取得するために使用されます。

  • isValid() −このメソッドは、キーが有効かどうかを天気予報で返します。

  • isReadable() −このメソッドは、ウェザーキーのチャネルが読み取り可能かどうかを示します。

  • isWritable() −このメソッドは、ウェザーキーのチャネルが書き込みの準備ができているかどうかを示します。

  • isAcceptable() −このメソッドは、ウェザーキーのチャネルが着信接続を受け入れる準備ができているかどうかを示します。

  • isConnectable() −このメソッドは、このキーのチャネルがソケット接続操作を終了したか、終了しなかったかをテストします。

  • isAcceptable() −このメソッドは、このキーのチャネルが新しいソケット接続を受け入れる準備ができているかどうかをテストします。

  • interestOps() −このメソッドは、このキーのインタレストセットを取得します。

  • readyOps() −このメソッドは、チャネルの準備ができている操作のセットである準備完了セットを取得します。

静的メソッドを呼び出すことにより、セレクターからチャネルを選択できます select().selectメソッドのselectが次のようにオーバーロードされます-

  • select() −このメソッドは、少なくとも1つのチャネルが登録されているイベントの準備ができるまで、現在のスレッドをブロックします。

  • select(long timeout) −このメソッドはselect()と同じように動作しますが、最大タイムアウトミリ秒(パラメーター)の間スレッドをブロックします。

  • selectNow() −このメソッドはまったくブロックしません。準備ができているチャネルがあれば、すぐに戻ります。

また、selectメソッドを呼び出すブロックされたスレッドを残すために、wakeup() メソッドはセレクターインスタンスから呼び出すことができ、その後select()内で待機しているスレッドはすぐに戻ります。

最後に、を呼び出すことでセレクターを閉じることができます close() セレクターを閉じるとともに、このセレクターに登録されているすべてのSelectionKeyインスタンスも無効にするメソッド。

import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

public class SelectorDemo {
   public static void main(String[] args) throws IOException {
      String demo_text = "This is a demo String";	
      Selector selector = Selector.open();
      ServerSocketChannel serverSocket = ServerSocketChannel.open();
      serverSocket.bind(new InetSocketAddress("localhost", 5454));
      serverSocket.configureBlocking(false);
      serverSocket.register(selector, SelectionKey.OP_ACCEPT);
      ByteBuffer buffer = ByteBuffer.allocate(256);
      while (true) {
         selector.select();
         Set<SelectionKey> selectedKeys = selector.selectedKeys();
         Iterator<SelectionKey> iter = selectedKeys.iterator();
         while (iter.hasNext()) {
            SelectionKey key = iter.next();
            int interestOps = key.interestOps();
            System.out.println(interestOps);
            if (key.isAcceptable()) {
               SocketChannel client = serverSocket.accept();
               client.configureBlocking(false);
               client.register(selector, SelectionKey.OP_READ);
            }
            if (key.isReadable()) {
               SocketChannel client = (SocketChannel) key.channel();
               client.read(buffer);
               if (new String(buffer.array()).trim().equals(demo_text)) {
                  client.close();
                  System.out.println("Not accepting client messages anymore");
               }
               buffer.flip();
               client.write(buffer);
               buffer.clear();
            }
            iter.remove();
         }
      }
   }
}