廖雪峰Java學習筆記 — 中斷執行緒與守護執行緒
技術標籤:廖雪峰Java學習筆記java多執行緒
1. 中斷執行緒
有時執行緒需要執行長時間的任務,比如下載一個1GB的大檔案,但或許由於網速過慢,導致使用者點選取消下載,這時就需要中斷這個執行緒。
在Java中,只需要在其他執行緒中對目標執行緒呼叫interrupt()
方法,然後目標執行緒反覆檢測自身狀態是否為interrupt
狀態,如果是,就立即結束。
示例程式碼:
public class Main {
public static void main(String[] args) throws InterruptedException {
Thread t = new MyThread();
t.start();
Thread.sleep(1);
t.interrupt();
t.join();
System.out.println("end");
}
}
class MyThread extends Thread {
public void run() {
int n = 0;
while (!isInterrupted()) {
n++;
System. out.println(n + " hello!");
}
}
}
上述程式碼中,在main()
函式中呼叫t.interrupt()
僅僅是給目標執行緒t
發了一箇中斷執行緒的訊號,還需要目標執行緒t
反覆檢測自身的interrupt
狀態。
同時,還發現在main()
函式中丟擲了一個InterruptedException
異常,該異常直接繼承至Exception
,為Checked Exception
,所以必須捕獲或者丟擲。
當一個執行緒呼叫了join()
等待其他執行緒結束時,被另一個執行緒呼叫了interrupt()
方法,就會立即丟擲InterruptedException
示例程式碼:
public class Main {
public static void main(String[] args) throws InterruptedException {
Thread t = new MyThread();
t.start();
Thread.sleep(1000);
t.interrupt(); // 中斷t執行緒
t.join(); // 等待t執行緒結束
System.out.println("end");
}
}
class MyThread extends Thread {
public void run() {
Thread hello = new HelloThread();
hello.start(); // 啟動hello執行緒
try {
hello.join(); // 等待hello執行緒結束
} catch (InterruptedException e) {
System.out.println("interrupted!");
}
hello.interrupt();
}
}
class HelloThread extends Thread {
public void run() {
int n = 0;
while (!isInterrupted()) {
n++;
System.out.println(n + " hello!");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
break;
}
}
}
}
上述程式碼中,MyThread
中呼叫hello.join()
方法後,會等待hello
執行緒結束。但此時main()
中對MyThread
執行緒呼叫了t.interrupt()
方法,使得hello.join()
立即丟擲InterruptedException
異常。
此外,執行緒間共享變數需要加上volatile
關鍵字。
2. 守護執行緒
當所有執行緒都結束時,程序才結束。
當有一些執行緒就是無限迴圈的,比如通過定時器執行緒來更新介面上的時間,如果這個執行緒不結束,JVM程序就無法結束。
通常這類執行緒被設定成守護執行緒,意思是指為其他執行緒服務的執行緒,當所有非守護執行緒都結束時,程序就會自動結束。
在Java中只需要呼叫start()
方法前,呼叫setDaemon(true)
即可把該執行緒設定為守護執行緒。
示例程式碼:
Thread t = new MyThread();
t.setDaemon(true);
t.start()