何爲Daemon線程?
Daemon----精靈,天使?
解釋這個問題之前先說清楚
Java的線程分爲兩類----用戶線程/Daemon線程
用戶線程:
用戶線程可以簡單地理解爲用戶自定義的線程,包括main線程
main線程其實不是一個daemon線程
舉例:main線程中創建一個用戶線程,然後print日誌,我們發現main結束了,線程仍然在運行,所以說明了main不是一個守護進程
Daemon線程(守護線程):
Daemon線程是爲我們創建的用戶線程提供服務的線程,比如說JVM的垃圾回收線程等等,這樣的線程有一個非常明顯的特徵:當用戶線程運行結束的時候,daemon線程就會自動退出。
特點:
A、守護線程創建的時候需要先調用setDaemon()進行設置,然後再啓動線程。
B、由於Daemon線程的終止條件是當前是否存在用戶線程,所以我們不能指派Daemon線程來進行一些業務操作,而只能服務用戶線程
C、Daemon線程創建的子線程任然是Daemon線程
基於其特點,我們可以知道,這樣的線程並不是用戶線程不可或缺的部分,只是用於提供服務的“服務線程”。所以,虛擬機中的用戶線程全部退出運行時,守護線程失去了服務的對象,JVM也就退出了。
記住一句話:線程中只剩下守護線程時,JVM就會退出。如果有任意一個線程存在,JVM就不會退出。
import java.util.Scanner;
public class DaemonRunner implements Runnable {
public void run() {
while (true) {
for (int i = 1; i <= 100; i++) {
System.out.println("守護線程:"+i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
Thread daemonThread = new Thread(new DaemonRunner());
// 設置爲守護進程
daemonThread.setDaemon(true);
daemonThread.start();
System.out.println("isDaemon = " + daemonThread.isDaemon());
Scanner sc = new Scanner(System.in);
// 接受輸入,使程序在此停頓,一旦接受到用戶輸入,main線程結束,JVM退出!
sc.next();
//AddShutdownHook方法增加JVM停止時要做處理事件:
//當JVM退出時,打印JVM Exit語句.
Runtime.getRuntime().addShutdownHook(new Thread(){
public void run() {
System.out.println("JVM has been Exited");
}
});
}
}
自定義守護進程的方法:
在Thread.start()方法之前使用setDaemon(true)方法
通過此方法將Thread類中的boolean daemon=true;
JVM就會將該線程歸爲守護線程。
注意的問題:
A、setDaemon()必須在Thread.start()之前使用
B、在守護線程中產生的線程也是守護線程
C、自己產生的守護線程要避免訪問數據庫、文件等資源,因爲JVM沒有用戶線程之後,守護線程立即終止