java.lang.Thread.interrupt()は何をしますか?


回答:


250

Thread.interrupt()ターゲットスレッドの割り込みステータス/フラグを設定します。次に、そのターゲットスレッドで実行されているコードが、中断されたステータスをポーリングして、適切に処理する場合があります。などのブロックするいくつかのメソッドはObject.wait()、中断されたステータスをすぐに消費し、適切な例外をスローします(通常InterruptedException

Javaでの割り込みは先制ではありません。別の言い方をすれば、割り込みを適切に処理するために両方のスレッドが協力しなければなりません。ターゲットスレッドが割り込みステータスをポーリングしない場合、割り込みは事実上無視されます。

ポーリングThread.interrupted()は、現在のスレッドの割り込みステータスを返し、その割り込みフラグをクリアするメソッドを介して行われます。通常、スレッドは、InterruptedExceptionをスローするなどの処理を実行します。

編集(Thiloコメントから):一部のAPIメソッドには、割り込み処理が組み込まれています。これには私の頭のてっぺんが含まれます。

  • Object.wait()、、Thread.sleep()およびThread.join()
  • ほとんどのjava.util.concurrent構造
  • Java NIO(java.ioは除く)を使用せずInterruptedException、代わりにを使用しClosedByInterruptExceptionます。

編集(完全を期すため@ thomas-porninまったく同じ質問に対する回答から)

スレッドの中断は、スレッドを軽く動かす方法です。出口へのスレッドにチャンスを与えるために使用されてきれいとは対照的に、Thread.stop()つまりより多くのアサルトライフルでスレッドを撮影のように。


22
sleepやwaitなどのメソッドはこの種のポーリングを行い、InterruptedExceptionを自分でスローすることに注意してください。
ティロ

1
割り込み可能なファイルI / Oを使用している場合、効果はそれほど穏やかではありません。通常、ファイルが破損します。
Marko Topolnik 2016年

Thread.interruptedについて言及している場合は、Thread.isInterruptedフラグもあることに言及する必要があるようです。このフラグはフラグをクリアしないため、通常、アプリケーション開発者による使用に適しています。
Nathan Hughes

67

割り込みとは?

割り込みは、スレッドが行っていることを停止し、別のことを行う必要があることをスレッドに示します。スレッドが割り込みにどのように応答するかを正確に決定するのはプログラマ次第ですが、スレッドが終了することは非常に一般的です。

どのように実装されていますか?

割り込みメカニズムは、割り込みステータスと呼ばれる内部フラグを使用して実装されます。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


これは部分的な説明に従います。また、割り込み可能なメソッドを中断します。
ローン侯爵、

@EJPこの質問は、Thread.interrupt()メソッドとは何か、およびそれがどのように機能するかについてです。私がリンクを付けて投稿したansは、質問された内容に答えると思います。私はまだあなたが何を望んでいるか理解していませんか?
YoK、

フラグによって実装されているという部分的に正しくないステートメントを修正してください。それは物語のほんの一部です。それは私にはかなりはっきりしているようです。
ローン侯爵

@EJPありがとう。今、私はあなたが言っていたことを理解しています。回答を更新し、メソッドのAPIドキュメントを追加しました。これは、私の答えから欠落していた割り込み可能なメソッド部分をカバーしています。私の答えが今完全に見えると思います:)。
YoK 2010

13

ターゲットとなるスレッドが(を呼び出すwait()か、または本質的に同じことを行う他の関連メソッド、sleep()中断さ待機を停止し、代わりにInterruptedExceptionを受け取ります。

それは完全にスレッド自体にかかっています(呼び出されたコード wait()この状況で何をするかを決定)です。スレッドは自動的には終了しません。

終了フラグと組み合わせて使用​​されることもあります。中断されると、スレッドはこのフラグをチェックし、それ自体をシャットダウンできます。しかし、これも単なる慣例です。


9歳、時代を超えた答え!+1
snr 2019

10

完全を期すために、他の回答に加えて、スレッドがブロックされる前などにスレッドが中断された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;
    }
}


4

スレッド割り込みは、フラグ割り込みステータスに基づいています。スレッドごとに、割り込みステータスのデフォルト値はfalseに設定されています。スレッドでinterrupt()メソッドが呼び出されるたびに、割り込みステータスがtrueに設定されます

  1. 割り込みステータス= true(interrupt()がすでにスレッドで呼び出されている)の場合、その特定のスレッドスリープ状態になりません。そのスレッドでスリープが呼び出されると、割り込み割り込み例外がスローされます。例外を再度スローした後、フラグはfalseに設定されます。
  2. スレッドがすでにスリープ状態で、interrupt()が呼び出された場合、スレッドはスリープ状態から抜け出し、割り込み例外をスローします。

1

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-現在のスレッドがこのスレッドを変更できない場合


1

割り込みは、スレッドが行っていることを停止し、別のことを行う必要があることをスレッドに示します。スレッドが割り込みにどのように応答するかを正確に決定するのはプログラマ次第ですが、スレッドが終了することは非常に一般的です。非常に良いリファレンス:https ://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html


1

Thread.interrupt()メソッドは、内部の「割り込みステータス」フラグを設定します。通常、そのフラグはThread.interrupted()メソッドによってチェックされます。

慣例により、 InterruptedExceptionを介して存在するメソッドは、割り込みステータスフラグをクリアする必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.