2

Javaでは、スレッドが一時停止し、I / O操作(Socket.read()やDataGramsocket.receive()など)のブロック中に他のスレッドに何らかの作業を行う機会を与えるという印象を受けました。マルチスレッドネットワークアプリケーションで何らかの理由で、receive()を呼び出すと、他のすべてのスレッドが不足します(receive()を呼び出したスレッドは大きなボスになり、制御を放棄することはないため、永久にブロックされます!)

なぜこれが起こるのでしょうか?以前はまったく同じアプリケーションを使用していましたが、UDPではなくTCPベースでした。Socket.read()は常にスレッドを一時停止し、ブロックが長すぎる場合は他の人が少しの間作業できるようにしました。

-追加情報-私のカスタムスレッドのTCPバージョンは次のコードでした: http ://www.dwgold.com/code/proxy/proxyThread.java.txt

私の新しいコード(UDPバージョン)はほとんど同じですが、UDPメソッドとスタイルを使用するように少し変更されています。次に、これらのスレッドを2つ作成し、両方でstartを呼び出します。最初のスレッドは常にブロックし、UDPバージョンで他のスレッドを機能させることはありません。

4

3 に答える 3

1

InputStreamを使用しているようで、InputStream.read()のJDKドキュメントによると、データが受信されるか、ファイルの終わりに到達するか、または例外がスローされます。

だから私にとって、質問は:なぜあなたのコードのTCPバージョンはブロックが中断されるのを許すのですか?それは意味がないようです。おそらく、TCPコードは、読み取りを個別の十分に短いバーストに分割し、スレッドがread()への個別の呼び出しの間にジャンプする機会があるのでしょうか。

さらに見てみると、違いは、コードのTCPバージョンがSocketによって提供されるInputStreamを介してデータを受信するのに対し、コードのUDPバージョンはDatagramSocket自体のreceive()メソッドから直接データを受信することです。したがって、これは2つ(InputStream.readとDatagramSocket.receive)によって提供される機能の根本的な違いにすぎないと思います。DatagramPacket.setSoTimeoutを使用してソケットの受信ブロックにタイムアウトを設定し、それがタイムアウトするreceive()の呼び出しによってスローされたときにSocketTimeoutExceptionをキャッチすることを考えましたか?あなたはあなたが望むものを達成するためにこれを実装することができるはずです。

更新:さらに詳しく見ると、DatagramSocket.receiveメソッドが同期されているようです。したがって、表示されている動作を説明する方法は、同じDatagramSocketインスタンスを使用しようとしている2つのスレッドを開始していることです。2つのスレッドが同じDatagramSocketインスタンスでreceive()を実行しようとすると、1つがブロックされます。完了するまでインスタンスを作成し、もう一方はブロックされます。(これについても説明しているSunフォーラムへの投稿があります。)これが起こっているのかもしれません-両方のスレッドに同じDatagramSocketを再利用していますか?

于 2009-11-23T17:32:41.077 に答える
0

これは、Java スレッドが (カーネル レベルのスレッドではなく) ユーザー レベルのスレッドであることが原因である可能性があります。1 つのカーネル レベル スレッドに、複数のユーザー レベル スレッドを含めることができます。ただし、1 つのユーザー レベル スレッドが io を待機する場合、カーネルはそのユーザー レベル スレッドだけを待機キューに入れる方法がなく、カーネル スレッド全体を待機キューに入れることしかできません (ユーザー レベル スレッドはユーザー レベルでスケジュールされ、カーネルレベルではありません)。その結果、io を待機している 1 つのユーザー レベル スレッドは、他のすべてのユーザー レベル スレッドを (そのカーネル スレッドから) ブロックすることができます。

于 2011-12-28T04:52:06.517 に答える
-1

あなたが説明している振る舞いについての説明は実際にはありません。ソケットからのInputStreamの読み取りにより、「他のすべてのスレッド」が一時停止するはずです。万が一、同じソケットから読み取っている複数のスレッドを開始しているのでしょうか。実際には、これらのスレッドがすべてハングしているということですか。その場合、ソケットから読み取ったデータはスレッド間で任意に分割されると思います。

于 2009-11-23T20:52:44.713 に答える