3

キャンセルを処理するスレッドでは、次のようなコードがよく見られます

while (!shutdown) {
  .. do something, if a blocking call, then it will throw the interrupted exception
  try { .. some more ... } 
  catch (InterruptedException e) { 
    shutdown = true; 
  }
}

私が知りたいのは、これであるか、なぜこれであるか、これを行うよりも優れている

try {
  while (true) {
    .. do something, if a blocking call, then it will throw the interrupted exception
    if (Thread.interrupted()) throw new InterruptedException();
  }
} catch (InterruptedException e) {
  .. clean up, let thread end
}

私の見方では、後者の場合、shutdownvarをまったく気にする必要はありません。

4

4 に答える 4

7

最初のバージョンでは、シャットダウンフラグ(または同様のシャットダウンメカニズム)を呼び出し元のコードと共有できるため、スレッドを中断することなく、フラグを設定するだけで完全に正常なシャットダウンを試みることができます。シャットダウンは失敗します。

唯一のシャットダウンメカニズムとしてスレッドの中断を使用することはお勧めしません。

(もちろん、共有フラグの処理方法にも注意してください。スレッドセーフにする必要があります。単純なケースでは、揮発性変数で十分でしょう。)

于 2011-04-01T12:05:20.440 に答える
2

2番目の方法はよりクリーンだと思います。これは、スレッドの中断に関するいくつかのI / Oの考慮事項も指摘している、同じ点に関する優れた記事です。 http://www.javaspecialists.eu/archive/Issue056.html

于 2011-04-01T12:10:48.943 に答える
2

条件を終了する方法として例外を使用しないでください(少なくとも通常はそうではなく、回避するのが最善の方法です)。例外は...キュードラム...例外、エラー、状況をアナウンスし、通常または潜在的に悪い状態。

シャットダウンは(通常は)エラー状態ではないため、少なくともその哲学的/設計の観点からは、シャットダウンフラグ変数を使用する最初のオプションをお勧めします。

また、フラグは読み取り専用プロパティとして(たとえば、ゲッターとして)外部化することができます。次に、スレッドの外部のコンポーネントは、スレッドがまだアクティブであるかどうかを確認できます(正当にそれに依存するロジックがある場合)。

個人的には、JavaがInterruptedExceptionを使用するのは嫌いです。これは、通常、例外ではなく、シグナル、通常は通常の予期されるシグナルであるためです。しかたがない。

于 2011-04-01T12:17:13.853 に答える
1

最終的にスレッドをクリーンアップするために使用することをお勧めします(これは常に呼び出されます)。ループを中断するためだけに例外をスローしないでください。試す

try {
  while (!Thread.interrupted()) {
    .. do something, if a blocking call, then it will throw the interrupted exception
  }
} catch (InterruptedException e) {
  // handle exception
} finally {
  .. clean up, let thread end
}
于 2011-04-01T12:34:26.620 に答える