The Java Tutorialsには非常によく表現された段落があります。
割り込みは、スレッドが実行していることを停止し、別のことを行う必要があることを示すものです。スレッドが割り込みにどのように応答するかを正確に決定するのはプログラマ次第ですが、スレッドが終了することは非常に一般的です。これは、このレッスンで強調されている使用法です。
スレッドを確実に停止して開始することは、並行アプリケーションを設計する上で重要な部分です。また、割り込みを目的を変更して目的を変更することもできますが、スレッドの終了を要求するという最も一般的な目的のために割り込みを残すと、コードの信頼性が向上し、他のユーザーにとって保守が容易になります。これは、20 秒のタイムアウトが終了する前にユーザーがアプリをシャットダウンすることを決定した場合に、おそらくやりたいことです。
では、元の問題を解決する方法 - あるスレッドが別のスレッドに作業を開始する時期であることを示すことができます。以下のクラスは、CountDownLatch を使用してこの問題を解決する方法を示しています。
新しいフー:
class Foo extends Thread
{
CountDownLatch latch = new CountDownLatch(1);
@Override
public void run()
{
try
{
boolean early = latch.await(20, TimeUnit.SECONDS);
System.out.println("Doing work " + (early ? "right away" : "after delay"));
// do real work here...
}
catch (InterruptedException e)
{
System.out.println("Interrupt detected. Exiting thread...");
}
}
public void goAhead()
{
latch.countDown();
}
}
「スリープ」を取り除き、ラッチ オブジェクトの await メソッドの呼び出しに置き換えます。foo を機能させるには、次のように呼び出します。
foo.goAhead(); // prints out "Doing work right away"
これにより、ラッチがカウントダウンします。「await」の呼び出しは、例外をスローして true を返すことなく、すぐに終了します。
foo をシャットダウンするには、次を使用します。
foo.interrupt(); // prints out "Interrupt detected..."
これにより、await はスリープと同様に InterruptedException をスローします。
または何もしないでください。await の呼び出しは 20 秒後にタイムアウトになり、例外をスローせずに false を返します。Fooは「遅延後に仕事をしています」と出力します
この設計の長期的な利点の 1 つは、「作業中」に他のブロッキング メソッドを呼び出す必要がある場合があることです。Interrupt を使用してそれらのいずれかに割り込むことができ、予期しないイベントに応答してスレッドを確実にシャットダウンするのに役立ちます。