短縮版:
Thread.interrupt() を使用しないことが既知のベスト プラクティスですか?
いいえ。
それが壊れている/バグがあり、堅牢なマルチスレッドコードを書くために使用すべきではない理由を証明できますか?
その逆です。マルチスレッド コードでは重要です。
例については、 Java Concurrency in Practiceのリスト 7.7 を参照してください。
より長いバージョン:
ここでは、このメソッドを 1 つの特定の場所で使用します: handlingInterruptedExceptions
です。少し奇妙に思えるかもしれませんが、コードでは次のようになります。
try {
// Some code that might throw an InterruptedException.
// Using sleep as an example
Thread.sleep(10000);
} catch (InterruptedException ie) {
System.err.println("Interrupted in our long run. Stopping.");
Thread.currentThread().interrupt();
}
これにより、次の 2 つのことが行われます。
- 割り込み例外を食べないようにします。IDE の自動例外ハンドラは、常に
ie.printStackTrace();
「TODO: 何か便利なものが必要です!」のようなものを提供します。コメント。
- このメソッドでチェック例外を強制することなく、割り込みステータスを復元します。
throws InterruptedException
実装しているメソッド シグネチャに句がない場合、これは中断されたステータスを伝達するための別のオプションです。
コメンターは、「スレッドを強制的に終了させるために」未チェックの例外を使用する必要があると提案しました。これは、スレッドを突然強制終了することが適切なことであるという事前の知識があることを前提としています。私はしません。
上記のリストの前のページで、JCIP の Brian Goetz を引用すると、次のようになります。
タスクは、特定の中断ポリシーを持つサービス内で実行するように明示的に設計されていない限り、実行中のスレッドの中断ポリシーについて何も想定しないでください。
たとえば、私がこれをしたと想像してください:
} catch (InterruptedException ie) {
System.err.println("Interrupted in our long run. Stopping.");
// The following is very rude.
throw new RuntimeException("I think the thread should die immediately", ie);
}
私は、コール スタックの残りの他の義務と関連する状態に関係なく、このスレッドは今すぐ終了する必要があると宣言します。他のすべての catch ブロックとステート クリーンアップ コードをこっそり通り過ぎて、スレッドの死に直行しようとします。さらに悪いことに、スレッドの割り込みステータスを消費していたでしょう。アップストリーム ロジックは、プログラム ロジック エラーがあったのか、それともチェック済み例外を不明瞭なラッパー内に隠そうとしているのかを突き止めるために、例外を分解する必要があります。
たとえば、チームの他の全員がすぐにやらなければならないことは次のとおりです。
try {
callBobsCode();
} catch (RuntimeException e) { // Because Bob is a jerk
if (e.getCause() instanceOf InterruptedException) {
// Man, what is that guy's problem?
interruptCleanlyAndPreserveState();
// Restoring the interrupt status
Thread.currentThread().interrupt();
}
}
中断された状態は、特定の よりも重要ですInterruptException
。理由の具体例については、Thread.interrupt()の javadoc を参照してください。
このスレッドが Object クラスの wait()、wait(long)、または wait(long, int) メソッド、または join()、join(long)、join(long, int) の呼び出しでブロックされている場合、sleep(long)、または sleep(long, int)、このクラスのメソッドの場合、その割り込みステータスはクリアされ、InterruptedException を受け取ります。
ご覧のとおり、割り込み要求が処理されるときに複数の InterruptedException が作成および処理される可能性がありますが、その割り込みステータスが保持されている場合に限られます。