文章目錄
- 1.概念
- 2.生命周期與行為
- 2. 應用場景
- 3. 示例代碼
- 4. 注意事項
1.概念
Daemon : 滴門
在Java中,線程分為兩類:用戶線程
(User Thread)和守護線程
(Daemon Thread)。
守護線程是后臺線程,主要服務于用戶線程,當所有的用戶線程結束時,守護線程也會自動結束,JVM會隨之退出。
守護線程的一個典型例子是垃圾回收線程。守護線程由JVM自己管理,不需要程序員手動結束。
總結:jvm等用戶線程全部執行完,然后拉著守護線程一起死。
2.生命周期與行為
啟動與運行:守護線程的啟動和普通線程一樣,通過調用start()方法進入就緒狀態,等待CPU調度執行。
終止條件:守護線程會在以下任一條件滿足時終止:
- 所有非守護線程結束執行。
- 顯式調用Thread.interrupt()或Thread.stop()(已廢棄)方法中斷線程。
- 程序中主動調用System.exit()結束JVM。
JVM退出:當最后一個非守護線程終止時,即使守護線程仍在執行某任務,JVM也會立即終止,不會等待守護線程完成其任務。
2. 應用場景
沒有特殊應用場景,守護線程可以做的事情用戶線程也可以做,只是比用戶線程少了一步線程間的通信。
守護線程的適用鐵律:
當且僅當任務可接受被隨時終止,且其終止不會導致數據損壞或邏輯錯誤時,使用守護線程。
在java web中沒必要使用:
因為在java web 中,比如用springboot 創建的web項目,springboot和其內嵌web服務器(比如tomcat)默認使用都是用戶線程,他們的生命周期與jvm是強綁定的,也就是說springboot項目中 若中止所有用戶線程,其整個jvm進程就會中止,守護線程又是由jvm管理的,所以springboot項目使用守護線程是沒有必要使用,用線程池更好創建用戶線程能更方便管理。
3. 示例代碼
創建守護線程
public class DaemonTest {public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(() -> {while (true){}},"t1");//如果沒有設置守護線程,主線程結束,t1線程不會結束t1.setDaemon(true);t1.start();TimeUnit.SECONDS.sleep(3);log.debug("main 結束");}
}
4. 注意事項
守護線程不能用作訪問持久化資源或者寫入文件,因為其會被jvm強行中止導致數據不一致。
守護線程的適用鐵律:
當且僅當任務可接受被隨時終止,且其終止不會導致數據損壞或邏輯錯誤時,使用守護線程。