守護執行緒與使用者執行緒
使用者執行緒:我們平常建立的普通執行緒。
守護執行緒:用來服務於使用者執行緒;不需要上層邏輯介入。
通過一個栗子來區分一下它們與JVM的關係。
class DaemonRunner implements Runnable {
@Override
public void run() {
while (true) {
for (int i = 1; i <= 100; i++) {
System.out.println("daemon thread:"+i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
Thread daemonThread = new Thread(new DaemonRunner());
daemonThread.setDaemon(true);
daemonThread.start();
System.out.println("isDaemon? = " + daemonThread.isDaemon());
Scanner scanner = new Scanner(System.in);
scanner.next();
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
System.out.println("JVM Exit!");
}
});
我們分析結果,可以得出結論:當執行緒只剩下守護執行緒的時候,JVM就會退出;補充一點如果還有其他的任意一個使用者執行緒還在,JVM就不會退出。
二使用它需要注意些什麼?
thread.setDaemon(true)必須在thread.start()之前設定,否則會跑出一個IllegalThreadStateException異常。你不能把正在執行的常規執行緒設定為守護執行緒。
在Daemon執行緒中產生的新執行緒也是Daemon的。
守護執行緒不能用於去訪問固有資源,比如讀寫操作或者計算邏輯。因為它會在任何時候甚至在一個操作的中間發生中斷。
Java自帶的多執行緒框架,比如ExecutorService,會將守護執行緒轉換為使用者執行緒,所以如果要使用後臺執行緒就不能用Java的執行緒池。
意義及應用場景
當主執行緒結束時,結束其餘的子執行緒(守護執行緒)自動關閉,就免去了還要繼續關閉子執行緒的麻煩。如:Java垃圾回收執行緒就是一個典型的守護執行緒;記憶體資源或者執行緒的管理,但是非守護執行緒也可以。
它的存在,必定有它的意義,只需在乎我們怎麼把它用到恰到好處。