私が書くなら:
int selectedChannels = selector.select(); selectedKeys = selector.selectedKeys(); を設定します。 if ( selectedChannels != selectedKeys.size() ) { // Selector.wakeup() の呼び出しにより Selector.select() が返されました // 同期も同様です。 } // 選択したチャネルの処理を続行します。
モーニングコールを正しく検出しますか?
背景情報:
ほとんどの場合、パケットを受信してファイルに保存するサーバーを作成しています。アプリケーションが自分自身に特別なパケットを送信する必要があることはほとんどありません。このために、(別のスレッドから) サーバーソケットへの接続を開始します。
SocketChannel channel = SocketChannel.open(); channel.configureBlocking( false ); channel.connect( new InetSocketAddress( InetAddress.getLocalHost(), PORT )); selector.wakeup(); SelectionKey キー = channel.register( セレクター、SelectionKey.OP_CONNECT );
問題は、メインスレッドがすでに Selector.select() にある場合、SelectableChannel.register() がブロックされる可能性があることです。これが起こらないようにするために、私は Selector.wakeup() を呼び出しています。これにより、メイン スレッドが select() から途中で戻ります。他のスレッドが登録呼び出しを完了する機会があることを確認するには、メイン スレッドを同期する必要がありますが、select() から戻るたびにそれを行う必要があります。wakeup() 呼び出しのために select() から返されたかどうかを検出できれば、この場合に最適化できます。
したがって、理論的にはトップ コード スニペットは機能するはずですが、特定されていない動作に依存しているため、機能するだけなのかどうか疑問に思っていました。
ヒントをありがとう。