java中有兩種線程: ①用戶線程;
②守護線程。
一、那麼什麼是守護線程?
對於用戶線程(非守護線程),當主線程停止時,用戶線程不受其影響,還可以執行,此時JVM是沒有停止運行的。而守護線程是當進程不存在或主線程停止,守護線程也會被停止,JVM也就退出。其實守護線程和用戶線程區別不大,可以理解爲特殊的用戶線程。特殊就特殊在如果程序中所有的用戶線程都退出了,那麼所有的守護線程就都會被殺死,很好理解,沒有被守護的對象了,也不需要守護線程了。
注意: 守護線程中產生的線程都是守護線程!
JVM 程序在什麼情況下能夠正常退出?
The Java Virtual Machine exits when the only threads running are all daemon threads.
上面這句話來自 JDK 官方文檔,意思是:
當 JVM 中不存在任何一個正在運行的非守護線程(用戶線程)時,則 JVM 進程即會退出。
二、如何創建守護線程?
①普通守護線程創建
創建一個用戶線程,然後調用setDaemon(true)方法將用戶線程轉化爲守護線程
thread.setDaemon(true);
注意:必須在線程啓動start()方法之前設置。
②利用Timer和TimerTask,創建守護線程
Timer是JDK提供的定時器工具,使用時會在主線程之外單獨起一個線程執行指定的任務。Timer timer = new Timer()啓動的是用戶線程,而Timer timer = new Timer()啓動的就是守護線程。TimerTask是一個實現了Runnable接口的抽象類,配合Timer使用可以看做被Timer執行的任務,即啓動的線程。
public class MyTask extends TimerTask{
Override
public void run(){
//要做的任務
}
}
public class ThreadDemo2{
public static void main(String[] args) throws InterruptedException {
Calendar calendar = new Calendar.getInstance();
//當前系統時間基礎上加10秒
calendar.add(Calendar.SECOND,10);
Date date = calendar.getTime();
MyTask task = new MyTask();
Timer timer = new Timer();
//當前時間10秒後執行“要做的任務”
timer.schedule(task,date);
}
}
三、守護線程應用
守護線程對於後臺支持任務非常有用,例如垃圾收集,釋放未使用對象的內存以及從緩存中刪除不需要的條目。大多數JVM線程都是守護線程。
JVM 中的垃圾回收線程就是典型的守護線程,如果說不具備該特性,會發生什麼呢?
當 JVM 要退出時,由於垃圾回收線程還在運行着,導致JVM無法退出,這樣一個程序只要運行就不會退出了,由此可見,守護線程的重要性了。
通常來說,守護線程經常被用來執行一些後臺任務,但是呢,你又希望在程序退出時,或者說 JVM 退出時,線程能夠自動關閉,此時,守護線程是你的首選。