コードで Threads.sleep を試すたびに、InterruptedException をキャッチする必要があります。これは、スレッドが指定した時間スリープできなかったことを意味しますよね? では、スリープ状態にしたスレッドをどのように中断できるのでしょうか? 誰でもこの概念を説明できますか?
5 に答える
スレッドを中断するにはどうすればよいですか? その上でThread.interrupt()を呼び出すことができます。
ここから:
割り込みは、スレッドが実行していることを停止し、別のことを行う必要があることを示すものです。スレッドが割り込みにどのように応答するかを正確に決定するのはプログラマ次第ですが、スレッドが終了することは非常に一般的です。これは、このレッスンで強調されている使用法です。
割り込みをきれいに処理する方法を理解するには、JavaSpecialistsのこの記事を読む価値があります。
ブライアン・アグニューが言ったように、例外sleep()
はへの反応interrupt()
です。ここでの概念は、スレッドがそれ自体を停止する方法を提供する必要があるということです。interrupted()
スリープしていない場合は、またはを介して割り込みステータスを時々チェックし、isInterrupted()
それに応じて対応する必要があります。しかし、スレッドがスリープしていて、その実行をキャンセルしたい場合は、運命にあります。スレッドはスリープしているだけで、interrupted
フラグを探す必要はありません。ただし、これが組み込みの動作ですsleep()
。スリープが終了する前にスレッドが中断されると、InterruptedExceptionが発生します。
指定された時間よりも早くスレッドが起動した場合、InterruptionException が発生します。
Execption は、特殊なケースを処理するオプションをユーザー (スレッド) に提供するためにのみスローされます。
最も一般的なケースでは、この execption をキャッチする必要はありません。私はそのための小さなヘルパーを好みます:
public class Sleeper {
private static final Logger log = Logger.getLogger(Sleeper.class);
/**
* @param time
* @param units
* @return milliseconds
*/
public static long sleepUnsafe(final long time, final TimeUnit units) {
final long start = System.currentTimeMillis();
final long millis = TimeUnit.MILLISECONDS.convert(time, units);
try {
Thread.sleep(millis);
} catch (final InterruptedException e) {
final long end = System.currentTimeMillis();
final long timeSlept = end - start;
final long difference = millis - timeSlept;
if (difference > 0) {
Sleeper.log.warn("should sleep for " + time + " " + units + ". But was awaked after " + (end - start) + " ms. Diffence is " + difference
+ "ms.");
return difference;
}
}
return 0;
}
/**
*
* @param millis
* @return
*/
public static long sleepUnsafe(final long millis) {
return Sleeper.sleepUnsafe(millis, TimeUnit.MILLISECONDS);
}
}
Java Concurrency In Practice (Peierls、Bloch、Bowbeer、Holmes、Lea)
たとえば、このスレッドがスリープしている間にアプリケーションがシャットダウンされている場合です。
アラームまたは別の外部イベントによって中断される可能性があります。