6

アプリケーションの反対側にある外部システムに接続して登録したクライアントを表すクラスのオブジェクトをインスタンス化する Java アプリケーションを作成しています。

各クライアント オブジェクトには、フロントエンドとバックエンドを表す 2 つのネストされたクラスがあります。フロントエンド クラスは継続的に実際のクライアントからデータを受信し、指示とデータをバックエンド クラスに送信します。バックエンド クラスはそのデータをフロントエンドから取得し、適切な形式とプロトコルを使用して外部システムに送信します。そのシステムが必要とします。

設計では、クライアント オブジェクトの各インスタンス化がスレッドになるようにしています。次に、各スレッド内には当然、[EDIT]それぞれ独自の NIO チャネルを持つ [/EDIT] 2 つのソケットがあり、1 つはクライアント側、もう 1 つはシステム側で、それぞれフロントエンドとバックエンドにあります。ただし、これにより、ノンブロッキング ソケットが必要になります。メインスレッドでセレクターを安全に使用して接続のあるすべてのスレッドを処理する方法を説明するチュートリアルを読んでいます。

しかし、必要なのは複数のセレクターで、それぞれが独自のスレッドで動作します。前述のチュートリアルを読んで、セレクターのキー セットはスレッドセーフではないことがわかりました。これは、それぞれにソケットとチャネルの独自のペアを与えようとすると、それぞれの個別のスレッドでインスタンス化された個別のセレクターが競合するキーを作成する可能性があることを意味しますか? セレクターをメイン スレッドに移動する可能性はわずかですが、与えられたソフトウェア要件に基づいて理想とはほど遠いものです。ご協力ありがとうございました。

4

2 に答える 2

3

複数のセレクターを使用することは、両方のセレクター インスタンスに同じ興味 (OP_READ / OP_WRITE など) を持つ同じチャネルを登録しない限り問題ありません。同じチャネルを複数のセレクター インスタンスに登録すると、selector1.select() が、selector2.select() が関心を持つ可能性のあるイベントを消費する可能性があるという問題が発生する可能性がありました。

ほとんどのプラットフォームのデフォルトのセレクターは、poll() [または epoll()] ベースです。

Selector.select は内部的にint poll( ListPointer, Nfdsmsgs, Timeout) method.

        where the ListPointer structure can then be initialized as follows:

    list.fds[0].fd = file_descriptorA;
    list.fds[0].events = requested_events;
    list.msgs[0].msgid = message_id;
    list.msgs[0].events = requested_events;

そうは言っても、ROX RPC nio チュートリアルで説明されているように、単一の選択スレッドを使用することをお勧めします。NIO の実装はプラットフォームに依存しており、あるプラットフォームで機能するものが別のプラットフォームでは機能しない可能性は十分にあります。マイナー バージョンでも問題が発生しています。たとえば、AIX JDK 1.6 SR2 は poll() ベースのセレクター - PollSelectorImpl と対応するセレクター プロバイダーを PollSelectorProvider として使用し、サーバーは正常に動作しました。pollset インターフェース・ベースの最適化されたセレクター (PollSetSelectorImpl) を使用する AIX JDK 1.6 SR5 に移行したとき、select() および socketchannel.close() でサーバーが頻繁にハングアップしました。理由の 1 つは、アプリケーションで複数のセレクターを開き (理想的な Selecting Thread モデルとは対照的に)、説明されているように PollSetSelectorImpl を実装していることです。ここに

于 2009-10-07T03:18:54.770 に答える