2017-12-21 8 views
1

私はそのソケットチャンネル&セレクターのキーをキャンセルするとセレクターでsocketchannelを登録しますが、そのキーは永久に無効のままです。したがって、セレクタにそのソケットチャネルを追加するための将来の呼び出しでは、CancelledKeyExceptionがスローされます。同じセレクターのsocketChannelの呼び出しは例外をスローする

Selection key = channel.register(selector, ops, this); 
key.cancel(); 
key = channel.register(selector, ops, this); 

マニュアル作成は同じことを述べて、だから、

If this key has already been cancelled then invoking this method has no 
effect. Once cancelled, a key remains forever invalid. 

、私は私が別の「選択キー」を得ることになったと思ったが、それは不可能です。登録すると、各チャンネルは各セレクタの固有のキーを作成しますが、そのキーをキャンセルすると、チャンネルのキーセットからキーを削除することはありません。だから、そのソケットチャネル&セレクターペアを使用することはできません。

正しいですか?この実装は意味をなさないので、私は何かが恋しくなることを願っています。

答えて

0

これは奇妙なものの1つです。私が探しているときに見つけられないドキュメントのどこかで、キャンセルは次のselect()でのみ処理されるというステートメントです。キャンセルの後で、第2のregister()の前にselectNow()に電話する必要があります。

しかし、なぜこれを介入せずにやっているのですか?select()は謎です。キーをキャンセルしないで、再登録しないでください:interestOpsを変更してください。

+0

ロードバランシング用です。スレッドはsocketchannelを受け取り、最初のメッセージを読み込み、セレクタから削除し、そのワーカーがそのワーカーを取得するかどうかを決定し、そのワーカーを宛先ワーカーに送信します。だから、もしdestがそれ自身であれば、それが問題になります。私はdest ==自身のチェックでそれを処理できますが、このSelectionKeyが実際にこのように動作するかどうかを知りたかったのです。答えてくれてありがとう。 – vkx

+0

これは間違いありません。別のセレクタに移動している場合はキャンセルするだけで済みますので、 'if(dest!=それ自身){key.cancel(); } '。同じセレクタの場合、後続の 'register()'は実際に更新された 'interestOps'と' attachment'で同じキーを返します。 – EJP

関連する問題