サーバーと多くのクライアントを同時に含む単純なアプリケーションを作成しています。DataGramSocketを使用する必要があります。アプリケーションは、チャットのようにコンソールを介してメッセージを交換するだけです。しかし、in.readLine()とds.receive()の両方の操作がブロックされており、それらを別々のスレッドに配置しても、i/oをブロックするとスレッドもブロックされるため役に立ちませんでした。どんな体でも、nioなしでそれを行う方法を教えてもらえますか
3 に答える
ネットワークを介したデータの送受信専用のスレッドがある場合、その専用スレッドのみがブロックされるため、スレッドのブロックは問題になりません。
次に、このソリューションがアプリケーションのスレッド数に与える影響を考えてみましょう。
- サーバーごとに少数のクライアントしかない場合、クライアントごとに 2 つの I/O スレッドがあっても問題ありません。
- サーバーごとに多数のクライアントがある場合は、要求の一部がすぐに処理されるのではなく、ワーカー スレッドが利用可能になるまで処理されないという事実を受け入れる必要があります。クライアントと同じ数の I/O スレッドの生成を試みることができますが、単一の JVM インスタンスが持つことができるスレッドの数には制限があります。正確な数値は、JVM で使用できるヒープのサイズと、アーキテクチャが 32 ビットか 64 ビットかによって異なります。こちらを参照してください。
多くのクライアントを処理する一般的なタスクに興味がある場合は、この質問に関する古典的な Web ペーパーを参照してください。
手動で生成されたスレッドまたはより優れたスレッド プール (http://www.ibm.com/developerworks/library/j-jtp0730.html) を使用して、個別のスレッドでブロック操作を実行することにより、これを行うことができます。
まず、java.nio を使用してノンブロッキング I/O を取得する必要があります。できないと仮定すると、何らかの理由で...
DatagramSocket とワークキュー (java.util.concurrent.ThreadPoolExecutor など) を使用して、サーバーで複数のクライアントからのデータを簡単に処理できます。
アイデアは、ソケットを読み取る単一の受信スレッドがあり、各データグラムが受信され、「ReceivedDatagram」オブジェクトにラップされ、ワークキューにドロップされるというものです。ワークキューにはスレッド プールがあり、そのスレッドは各パケットをキューから取り出して処理します。パケットが応答を必要とする場合、スレッドは別の ReceivedDatagram をデキューするためにブロックする前に応答 (ブロック) を送信します。
データを非同期に送信するには、送信する DatagramPacket を表す「SendDatagram」オブジェクトを作業キューに置くだけです。
Datagram.receive(DatagramPacket) と Datagram.send(DatagramPacket) を使用することに注意してください。