0

私のアプリケーションでは、複数のスレッドを使用してクライアント接続を処理しています。

デバッグ時に非常に奇妙な動作を見つけました - (デバッガーを使用して) InterestOps() メソッドを呼び出すことによって戻り値が 1 (READ) である SelectionKey がありますが、そのキーに対応するソケットにデータを送信すると、セレクターはそうではありません。目覚める..

デバッガーを使用して、特定の選択キーの対象操作を 1 に変更すると (1 だったとしても)、セレクターが突然その変更に反応します。

特定の時点で接続を処理するスレッドは 1 つしかありませんが、このスレッドはその接続に固有のものではありません。マルチスレッドを無効にすると (スレッド プールのサイズを 1 に設定すると)、この問題は発生しませんでした。

SelectionKey クラスのドキュメントを見ると、このメソッドはスレッド セーフである必要があります。

4

4 に答える 4

3

スレッドセーフの問題ではありません。現在進行中の場合はselect()、登録されているすべてのキーからすべてのinterestOpsが既に読み取られており、読み取ったときの値を選択しています。値はオペレーティングシステムに渡され、オペレーティングシステムのブロック操作が進行中です。 。選択操作の途中でを変更してもinterestOps、その選択操作には影響せず、次の操作にのみ影響します。

于 2012-07-18T03:47:25.913 に答える
2

セレクタースレッドで行われるようにinterestOpsへのすべての変更を移動した後、問題は解決しました-したがって、interestOps(int)はスレッドセーフではないと思います。

すべてのinterestOpsの変更をセレクタースレッドに移動して編集
します。また、30%のスピードアップが得られます。理由はわかりませんが、これが私のテスト間の唯一の変更です。

于 2012-07-17T14:33:36.370 に答える
0

私はパーティーに少し遅れましたが、私のように将来訪問する人のために:

「選択キーは、複数の同時スレッドで安全に使用できます。一般に、対象セットの読み取りと書き込みの操作は、セレクターの特定の操作と同期されます。」

「Java 7のSelectionKey」から取得

于 2016-11-04T08:15:22.573 に答える