🐬

Javaのスレッドに割り込みをして停止する

2024/07/16に公開

はじめに

今回はJavaのスレッドに割り込みをして強制停止する方法について調査しました。

スレッドに割り込みをして停止する

interruptメソッドを使用すると、スレッドでInterruptedExceptionを発生させて、スレッドの処理を終了させることができます。

TestMain.java
public class TestMain {
    public static void main(String[] args) {
        try {

            // スレッドを起動
            TestThread testThread = new TestThread();
            Thread thread = new Thread(testThread);    
            thread.start();

            // 3秒待機してからスレッドに割り込みを送る
            Thread.sleep(3000);
            System.out.println("Interrupt !!");
            thread.interrupt();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
TestThread.java
// 10秒間スリープするスレッド
public class TestThread implements Runnable {
    @Override
    public void run() {
        try {

            System.out.println("Thread sleep start");
            // 10秒までスリープ
            for (int i = 1; i <= 10; i++) {
                System.out.println("Thread sleep: " + i);
                Thread.sleep(1000);
            }
            System.out.println("Thread sleep end");

        } catch (InterruptedException e) {
            System.out.println("Thread InterruptedException");
        }
    }
}
実行結果
Thread sleep start
Thread sleep: 1
Thread sleep: 2
Thread sleep: 3
Interrupt !!
Thread InterruptedException

一定時間経過しても終了しないスレッドを停止する

スレッドが一定時間経過しても終了しない場合に、割り込みをして強制停止するには下記の様に処理します。

joinメソッドで最大待機時間を設定してスレッドが終了まで待機します。
最大待機時間を経過してもスレッドが稼働している場合は、interruptメソッドで割り込みを送信してスレッドを停止します。

TestMain.java
public class TestMain {
    public static void main(String[] args) {
        try {

            // スレッドを起動
            TestThread testThread = new TestThread();
            Thread thread = new Thread(testThread);    
            thread.start();

            // スレッドの終了を最大5秒待機 
            try {
                thread.join(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            // スレッドが稼働しているか確認
            if (thread.isAlive()) {
                // スレッドが稼働している場合は割り込みを送る
                System.out.println("interrupt !!");
                thread.interrupt();

                // スレッドの終了まで待機
                try {
                    thread.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Thread stop");
            } else {
                System.out.println("Thread is not alive");
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
実行結果
Thread sleep start
Thread sleep: 1
Thread sleep: 2
Thread sleep: 3
Thread sleep: 4
Thread sleep: 5
interrupt !!
Thread InterruptedException
Thread stop

joinメソッドの最大待機時間を20秒に変更して実行すると、待機時間を超える前にスレッドが終了し、interruptメソッドの割り込みは送信されないことが確認できます。

// thread.join(5000);
thread.join(20000);
実行結果
Thread sleep start
Thread sleep: 1
Thread sleep: 2
Thread sleep: 3
Thread sleep: 4
Thread sleep: 5
Thread sleep: 6
Thread sleep: 7
Thread sleep: 8
Thread sleep: 9
Thread sleep: 10
Thread sleep end
Thread is not alive
レスキューナウテックブログ

Discussion