要使任務和線程能安全可靠地停止,並不是一件很容易的事情,java沒有提供任何機制來安全地終止線程,那麼我們該怎麼辦呢?
下面我們先來了解一下java中的中斷機制:

java中斷機制是一種協作機制,也就是說在某個線程中對另一個線程調用interrupt()方法並不能直接終止該線程,需要被中斷的線程自己處理中斷請求
interrupted() 和 isInterrupted()的主要區別:
非靜態方法isInterrupted()用來查詢某線程的中斷狀態,且不會改變該線程的中斷狀態標識;
靜態方法interrupted()檢查中斷狀態時,中斷狀態會被清零(置為false)。
在下面的例子中,主線程通過調用t.interrupt()方法將線程t的中斷狀態設置為true,線程t可以在合適的時候調用interrupted()方法或isInterrupted()方法來檢測其中斷狀態並做相應處理:
package com.test;
public class ThreadTest extends Thread {
public void run() {
while (true) {
if (Thread.interrupted()) {
System.out.println("Someone interrupted me.");
break;
} else {
System.out.println("Going...");
}
long now = System.currentTimeMillis();
while (System.currentTimeMillis() - now < 1000) {
//讓循環持續一段時間,打印的輸出語句會少一些
}
}
}
public static void main(String[] args) throws InterruptedException {
ThreadTest t = new ThreadTest();
t.start();
Thread.sleep(3000);
t.interrupt();
}
}
結果如下:
Going... Going... Going... Someone interrupted me.
(1)對於非阻塞中的線程, 只是改變了中斷狀態, 即Thread.isInterrupted()將返回true;
(2)對於可取消的阻塞狀態中的線程, 比如等待在Thread.sleep(), Object.wait(), Thread.join(),這些函數上的線程, 這個線程收到中斷信號後, 會拋出InterruptedException, 同時會把中斷狀態置回為false.
下面這段程序會使得阻塞在Thread.join()方法上的主線程在收到中斷信號後結束:
package com.test;
public class ThreadTest extends Thread {
private Thread parent;
public ThreadTest(Thread parent){
this.parent = parent;
}
public void run() {
while (true) {
System.out.println("sub thread is running...");
long now = System.currentTimeMillis();
while (System.currentTimeMillis() - now < 2000) {
//讓循環持續一段時間,打印的輸出語句會少一些
}
parent.interrupt();
}
}
public static void main(String[] args){
ThreadTest t = new ThreadTest(Thread.currentThread());
t.start();
try {
t.join();
} catch (InterruptedException e) {
System.out.println("Parent thread will die...");
}
}
}
結果如下:
sub thread is running... Parent thread will die... sub thread is running... sub thread is running... sub thread is running... sub thread is running...
從結果可以看出,線程t發出中斷請求後主線程結束(此時線程t仍在運行)