0

ソケットからデータを読み取るスレッド(T1としましょう)があります:

public void run() {
  while (running) {
    try {
      BufferedReader reader = new BufferedReader( new InputStreamReader(socket.getInputStream()) ); 
      String input = reader.readLine();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

}

別のスレッド (T2 としましょう) は、そのメソッドの 1 つでプログラムを終了しようとします。したがって、T2 は次のことを行います。

T1.running = false;
socket.close();

解決策が見つからなかったこのシナリオは次のとおりです。

  • T1 はアクティブで、何らかの入力の読み取り、つまりブロッキングを待機しています。
  • コンテキスト切り替え
  • T2 がアクティブで、running を false に設定し、ソケットを閉じます
  • コンテキスト切り替え
  • T1 がブロックしていて、T2 がソケットを閉じたため、T1 は例外をスローします。私が欲しいのは、この SocketException をキャッチすることです。T1.run() に try/catch(SocketException) を入れることができません。では、T1 の実行方法でそれをキャッチするにはどうすればよいですか? T1 の実行中にそれをキャッチすることができない場合、どうすれば他の場所でキャッチできますか?

PS: 「スレッドのデバッグに関する別の質問」
通常、コードを段階的にデバッグすると、コンテキスト スイッチで「アクティブな実行中の行」が失われます。私が T1 の 20 行目にいるとしましょう。コンテキスト スイッチが発生します。プログラムが T2 の 30 行から続行すると仮定しますが、デバッガーは T2 の 30 行に移動/表示せず、代わりに「アクティブな実行中の行」に移動します。 '消えます。そのため、コードを制御できなくなります。Java には Eclipse を、C# には Visual Studio を使用しています。では、コンテキスト スイッチでのデバッグ中にコードを追跡する最善の方法は何でしょうか?

4

2 に答える 2

1

スレッドプールを使用していると仮定して問題を解決するには、すべてのスレッドに Thread.UncaughtExceptionHandler をインストールする ThreadFactory を作成し、submit() の代わりに ExecutorService で execute() を使用して作業を呼び出す必要があります。

デバッグに問題がある場合は、 http://msdn.microsoft.com/en-us/library/ms164746.aspxを読む必要があります。

于 2012-11-28T05:09:53.910 に答える
1

あなたのコードには他にもいくつかの問題があるので、それらすべてに同時に対処します。

  1. ループのBufferedReader 外側を作成する必要があります。そうしないと、ループのたびに破棄されるバッファー内のデータが失われます。
  2. readLine()for nullの結果をテストする必要があります。取得した場合は、を閉じてBufferedReaderループを終了する必要があります。
  3. 例外が発生した場合はBufferedReader、ループを閉じて終了する必要もあります。

私が欲しいのは、この SocketException をキャッチすることです。

だから捕まえろ。

T1.run() に try/catch(SocketException) を入れることができません。

絶対です。選択の余地ない。上記の項目があるため、とにかく完全に書き直す必要があります。

于 2012-11-28T06:31:33.520 に答える