このレッスンでは、 Selectorクラスについて学びます。このクラスはjava.nio.channelsパッケージに含まれているため、使用するために何もダウンロードしたり設定したりする必要はありません。Selectorオブジェクトは、1 つ以上のChannelオブジェクトを監視し、読み取り/書き込みの準備ができているかなどを確認できます。そして最も重要なことは、セレクターにはチャネルごとに 1 つのストリームではなく、1 つのストリームが必要であるということです

静的openメソッドを使用してセレクターを作成します。


Selector selector = Selector.open();

その後、チャンネルをセレクター オブジェクトに登録できます。


SelectionKey key1 = channel1.register(selector, SelectionKey.OP_READ);
SelectionKey key2 = channel2.register(selector, SelectionKey.OP_WRITE);

registerメソッドの 2 番目のパラメーターは、セレクターがどの操作を監視するかを決定します。複数の操作を一度に監視する必要がある場合は、ビットごとの OR を使用できます。


SelectionKey.OP_READ | SelectionKey.OP_WRITE

いずれかのチャネルで I/O アクションが発生すると、セレクターが通知します。これにより、たとえば、多数のデータ ソースからデータを読み取ることができます。

ここで、チャネルをセレクターで使用するには、チャネルがノンブロッキング モードである必要があることに注意する必要があります。


channel1.configureBlocking(false);
channel2.configureBlocking(false);
SelectionKey key1 = channel1.register(selector, SelectionKey.OP_READ);
SelectionKey key2 = channel2.register(selector, SelectionKey.OP_WRITE);

FileChannelは非ブロッキング モードに切り替えることができないため、セレクターはFileChannelでは機能しません ( configureBlockingメソッドはSelectableChannelクラスで宣言されており、FileChannelは継承しません)。

この図から、セレクターがソケットでの使用に適していることがわかります。2 番目のモジュールの最後で一緒に作業します。

選択キー

チャンネルをセレクターに登録すると、選択キー物体。このオブジェクトには、チャネル登録に関するデータが含まれています。

キーを使用して、チャネルが特定の値を受け入れる準備ができているかどうかを判断できます。


key.isReadable()
key.isAcceptable()
key.isConnectable()
key.isWritable()

キーにより、対応するチャンネルとセレクターが表示されます。


Channel channel = key.channel();
Selector selector = key.selector();

今後追跡するために、任意のオブジェクトをキーにアタッチできます。これは、チャネル登録中 (3 番目の引数を介して) または後で実行できます。

  1. SelectionKey キー = channel.register(selector, SelectionKey.OP_ACCEPT, object);

  2. key.attach(オブジェクト);

後で、キーから添付されたオブジェクトを取得できます。


Object object = key.attachment();

結論

セレクターを使用してチャンネルを登録すると、次のことが可能になります。

  • 指定された操作を実行する準備ができているチャネルの数を調べます
  • 少なくとも 1 つのチャネルの準備ができるまでプログラムの実行をブロックします
  • 準備ができたチャネルのキーのセットを取得します
  • もっと

2 番目のモジュールの最後では、セレクターを実際に試してみましょう。