🐬
Javaのスレッドに割り込みをして停止する
はじめに
今回は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