java.lang.Thread.interrupt()
呼び出されたときに何が起こるか説明できますか?
java.lang.Thread.interrupt()
呼び出されたときに何が起こるか説明できますか?
回答:
Thread.interrupt()
ターゲットスレッドの割り込みステータス/フラグを設定します。次に、そのターゲットスレッドで実行されているコードが、中断されたステータスをポーリングして、適切に処理する場合があります。などのブロックするいくつかのメソッドはObject.wait()
、中断されたステータスをすぐに消費し、適切な例外をスローします(通常InterruptedException
)
Javaでの割り込みは先制ではありません。別の言い方をすれば、割り込みを適切に処理するために両方のスレッドが協力しなければなりません。ターゲットスレッドが割り込みステータスをポーリングしない場合、割り込みは事実上無視されます。
ポーリングThread.interrupted()
は、現在のスレッドの割り込みステータスを返し、その割り込みフラグをクリアするメソッドを介して行われます。通常、スレッドは、InterruptedExceptionをスローするなどの処理を実行します。
編集(Thiloコメントから):一部のAPIメソッドには、割り込み処理が組み込まれています。これには私の頭のてっぺんが含まれます。
Object.wait()
、、Thread.sleep()
およびThread.join()
java.util.concurrent
構造InterruptedException
、代わりにを使用しClosedByInterruptException
ます。編集(完全を期すため、@ thomas-porninのまったく同じ質問に対する回答から)
スレッドの中断は、スレッドを軽く動かす方法です。出口へのスレッドにチャンスを与えるために使用されてきれいとは対照的に、Thread.stop()
つまりより多くのアサルトライフルでスレッドを撮影のように。
割り込みとは?
割り込みは、スレッドが行っていることを停止し、別のことを行う必要があることをスレッドに示します。スレッドが割り込みにどのように応答するかを正確に決定するのはプログラマ次第ですが、スレッドが終了することは非常に一般的です。
どのように実装されていますか?
割り込みメカニズムは、割り込みステータスと呼ばれる内部フラグを使用して実装されます。Thread.interruptを呼び出すと、このフラグが設定されます。スレッドが静的メソッドThread.interruptedを呼び出して割り込みを確認すると、割り込みステータスがクリアされます。あるスレッドが別のスレッドの割り込みステータスを照会するために使用する非静的Thread.isInterruptedは、割り込みステータスフラグを変更しません。
Thread.interrupt()
APIからの引用:
このスレッドに割り込みます。最初に、このスレッドのcheckAccessメソッドが呼び出されます。これにより、SecurityExceptionがスローされる場合があります。
Objectクラスの、またはjoin()、join(long)、join(long、int)のwait()、wait(long)、またはwait(long、int)メソッドの呼び出しでこのスレッドがブロックされた場合、sleep(long)、またはsleep(long、int)のメソッドの場合、その割り込みステータスはクリアされ、InterruptedExceptionを受け取ります。
このスレッドが割り込み可能なチャネルのI / O操作でブロックされている場合、チャネルは閉じられ、スレッドの割り込みステータスが設定され、スレッドはClosedByInterruptExceptionを受け取ります。
このスレッドがセレクターでブロックされると、スレッドの割り込みステータスが設定され、セレクターのウェイクアップメソッドが呼び出された場合と同様に、選択操作からすぐに返されます。
上記の条件のいずれも満たされない場合、このスレッドの割り込みステータスが設定されます。
同じことを完全に理解するためにこれをチェックしてください:
http://download.oracle.com/javase/tutorial/essential/concurrency/interrupt.html
完全を期すために、他の回答に加えて、スレッドがブロックされる前などにスレッドが中断されたObject.wait(..)
場合Thread.sleep(..)
、これは、次の例に示すように、そのメソッドでブロックされた直後に中断されるのと同じです。
public class InterruptTest {
public static void main(String[] args) {
Thread.currentThread().interrupt();
printInterrupted(1);
Object o = new Object();
try {
synchronized (o) {
printInterrupted(2);
System.out.printf("A Time %d\n", System.currentTimeMillis());
o.wait(100);
System.out.printf("B Time %d\n", System.currentTimeMillis());
}
} catch (InterruptedException ie) {
System.out.printf("WAS interrupted\n");
}
System.out.printf("C Time %d\n", System.currentTimeMillis());
printInterrupted(3);
Thread.currentThread().interrupt();
printInterrupted(4);
try {
System.out.printf("D Time %d\n", System.currentTimeMillis());
Thread.sleep(100);
System.out.printf("E Time %d\n", System.currentTimeMillis());
} catch (InterruptedException ie) {
System.out.printf("WAS interrupted\n");
}
System.out.printf("F Time %d\n", System.currentTimeMillis());
printInterrupted(5);
try {
System.out.printf("G Time %d\n", System.currentTimeMillis());
Thread.sleep(100);
System.out.printf("H Time %d\n", System.currentTimeMillis());
} catch (InterruptedException ie) {
System.out.printf("WAS interrupted\n");
}
System.out.printf("I Time %d\n", System.currentTimeMillis());
}
static void printInterrupted(int n) {
System.out.printf("(%d) Am I interrupted? %s\n", n,
Thread.currentThread().isInterrupted() ? "Yes" : "No");
}
}
出力:
$ javac InterruptTest.java
$ java -classpath "." InterruptTest
(1) Am I interrupted? Yes
(2) Am I interrupted? Yes
A Time 1399207408543
WAS interrupted
C Time 1399207408543
(3) Am I interrupted? No
(4) Am I interrupted? Yes
D Time 1399207408544
WAS interrupted
F Time 1399207408544
(5) Am I interrupted? No
G Time 1399207408545
H Time 1399207408668
I Time 1399207408669
含意:次のようにループし、制御が終了Thread.sleep(..)
してループを迂回しているちょうどその時に割り込みが発生した場合、例外は引き続き発生します。したがって、スレッドが中断された後、InterruptedExceptionが確実にスローされることに依存することは完全に安全です。
while (true) {
try {
Thread.sleep(10);
} catch (InterruptedException ie) {
break;
}
}
Thread.interrupt()
ターゲットスレッドの中断ステータス/フラグをtrueに設定します。これを使用してチェックThread.interrupted()
すると、無限スレッドの停止に役立ちます。http://www.yegor256.com/2015/10/20/interrupted-exception.htmlを参照してください
スレッド割り込みは、フラグ割り込みステータスに基づいています。スレッドごとに、割り込みステータスのデフォルト値はfalseに設定されています。スレッドでinterrupt()メソッドが呼び出されるたびに、割り込みステータスがtrueに設定されます。
public void interrupt()
このスレッドに割り込みます。
常に許可されている現在のスレッドがそれ自体を中断している場合を除き、このスレッドのcheckAccessメソッドが呼び出され、SecurityExceptionがスローされる場合があります。
このスレッドが、Objectクラス、またはjoin()、join(long)、join(long、int)のwait()、wait(long)、またはwait(long、int)メソッドの呼び出しでブロックされた場合、sleep(long)、またはsleep(long、int)のメソッドの場合、その割り込みステータスはクリアされ、InterruptedExceptionを受け取ります。
このスレッドが割り込み可能なチャネルのI / O操作でブロックされている場合、チャネルは閉じられ、スレッドの割り込みステータスが設定され、スレッドはClosedByInterruptExceptionを受け取ります。
このスレッドがセレクターでブロックされると、スレッドの割り込みステータスが設定され、セレクターのウェイクアップメソッドが呼び出された場合と同様に、選択操作からすぐに返されます。
上記の条件のいずれも満たされない場合、このスレッドの割り込みステータスが設定されます。
生存していないスレッドを中断しても、何の影響もありません。
例外:SecurityException-現在のスレッドがこのスレッドを変更できない場合