回答:
これは状態を維持するために行われます。
をキャッチしてInterruptException
それを飲み込むと、基本的に、上位レベルのメソッド/スレッドグループが割り込みに気付くことを防ぎます。問題が発生する可能性があります。
を呼び出すことによりThread.currentThread().interrupt()
、スレッドの割り込みフラグを設定します。これにより、高レベルの割り込みハンドラーがそれを認識し、適切に処理できるようになります。
Java Concurrency in Practiceでは、これについて第7.1.3章:割り込みへの応答で詳しく説明しています。そのルールは:
スレッドの割り込みポリシーを実装するコードだけが、割り込み要求を飲み込むことができます。汎用タスクとライブラリコードは、割り込み要求を決して飲み込むべきではありません。
interrupt()
呼び出しが割り込みフラグを設定する唯一の方法であることにも注意してくださいInterruptedException
。
このコードサンプルは、少しわかりやすいと思います。仕事をするクラス:
public class InterruptedSleepingThread extends Thread {
@Override
public void run() {
doAPseudoHeavyWeightJob();
}
private void doAPseudoHeavyWeightJob() {
for (int i=0;i<Integer.MAX_VALUE;i++) {
//You are kidding me
System.out.println(i + " " + i*2);
//Let me sleep <evil grin>
if(Thread.currentThread().isInterrupted()) {
System.out.println("Thread interrupted\n Exiting...");
break;
}else {
sleepBabySleep();
}
}
}
/**
*
*/
protected void sleepBabySleep() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
//e.printStackTrace();
Thread.currentThread().interrupt();
}
}
}
メインクラス:
public class InterruptedSleepingThreadMain {
/**
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
InterruptedSleepingThread thread = new InterruptedSleepingThread();
thread.start();
//Giving 10 seconds to finish the job.
Thread.sleep(10000);
//Let me interrupt
thread.interrupt();
}
}
ステータスを元に戻さずに割り込みを呼び出してみてください。
注意:
長時間(たとえば、入力待ち)になっているスレッドを停止するにはどうすればよいですか?
この手法が機能するには、割り込み例外をキャッチし、それに対処する準備ができていないメソッドがすぐに例外を再アサートすることが重要です。例外を再スローできるとは限らないため、再スローではなく再アサートと言います。InterruptedExceptionをキャッチするメソッドがこの(チェックされた)例外をスローするように宣言されていない場合は、次のように「それ自体を再割り込み」する必要があります。
Thread.currentThread().interrupt();
これにより、スレッドはできる限りすぐにInterruptedExceptionを再発生させます。
私はそれを悪い習慣だと思うか、少なくとも少し危険だと思います。通常、より高いレベルのメソッドはブロッキング操作を実行せず、InterruptedException
そこに表示されることはありません。割り込み可能な操作を実行するすべての場所でそれをマスクすると、それを取得することはできません。
Thread.currentThread.interrupt()
他の例外(シグナルのinterrupted
ローカルループ変数をスレッドのメインループに設定するなど)で発生したり、他の例外を発生させたり、シグナルを送信したりしない唯一の理由は、finally
ブロックのように、例外を使用して実際には何もできない状況です。
Thread.currentThread.interrupt()
通話の意味をよりよく理解したい場合は、PéterTörökの回答を参照してください。
java docから参照
このスレッドがwait()、join()、sleep(long)の呼び出しでブロックされている場合、その割り込みステータスはクリアされ、InterruptedExceptionを受け取ります。
このスレッドがI / O操作でブロックされると、スレッドの割り込みステータスが設定され、スレッドはClosedByInterruptExceptionを受け取ります。
このスレッドがセレクターでブロックされている場合、スレッドの割り込みステータスが設定され、選択操作からすぐに戻ります。
前の条件のいずれも保持しない場合、このスレッドの割り込みステータスが設定されます。
そのため、@ Ajay George AnswerのsleepBabySleep()メソッドをI / O操作または単にsysoutに変更した場合、ステータスを元に戻してプログラムを停止する必要はありません。(ところで、InterruptedExceptionはスローされません)
@PéterTörökが言ったように=>これは状態を維持するために行われます。(特に、InterruptedExceptionをスローするメソッドの場合)
InterruptedException
ステータス割り込みクリアが。それがそうするとき、私は、これはの面で答え明確になると思う理由を。あなたが割り込みステータスを保持する必要がある