什么是守護線程?


Java線程分為用戶線程和守護線程。

  • 守護線程是程序運行的時候在后台提供一種通用服務的線程。所有用戶線程停止,進程會停掉所有守護線程,退出程序。
  • Java中把線程設置為守護線程的方法:在 start 線程之前調用線程的 setDaemon(true) 方法。

 

注意:

  • setDaemon(true) 必須在 start() 之前設置,否則會拋出IllegalThreadStateException異常,該線程仍默認為用戶線程,繼續執行
  • 守護線程創建的線程也是守護線程
  • 守護線程不應該訪問、寫入持久化資源,如文件、數據庫,因為它會在任何時間被停止,導致資源未釋放、數據寫入中斷等問題
package constxiong.concurrency.a008;

/**
 * 測試守護線程
 * @author ConstXiong
 * @date 2019-09-03 12:15:59
 */
public class TestDaemonThread {

    public static void main(String[] args) {
        testDaemonThread();
    }
    
    //
    public static void testDaemonThread() {
        Thread t = new Thread(() -> {
            //創建線程,校驗守護線程內創建線程是否為守護線程
            Thread t2 = new Thread(() -> {
                System.out.println("t2 : " + (Thread.currentThread().isDaemon() ? "守護線程" : "非守護線程"));
            });
            t2.start();
            
            //當所有用戶線程執行完,守護線程會被直接殺掉,程序停止運行
            int i = 1;
            while(true) {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("t : " + (Thread.currentThread().isDaemon() ? "守護線程" : "非守護線程") + " , 執行次數 : " + i);
                if (i++ >= 10) {
                    break;
                }
            }
        });
        //setDaemon(true) 必須在 start() 之前設置,否則會拋出IllegalThreadStateException異常,該線程仍默認為用戶線程,繼續執行
        t.setDaemon(true);
        t.start();
        
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //主線程結束
        System.out.println("主線程結束");
    }
    
}

 

執行結果

t2 : 守護線程
t : 守護線程 , 執行次數 : 1
主線程結束
t : 守護線程 , 執行次數 : 2

 

 

結論:

  • 上述代碼線程t,未打印到 t : daemon thread , time : 10,說明所有用戶線程停止,進程會停掉所有守護線程,退出程序
  • 當 t.start(); 放到 t.setDaemon(true);  之前,程序拋出IllegalThreadStateException,t 仍然是用戶線程,打印如下
Exception in thread "main" t2 : 非守護線程
java.lang.IllegalThreadStateException
    at java.lang.Thread.setDaemon(Thread.java:1359)
    at constxiong.concurrency.a008.TestDaemonThread.testDaemonThread(TestDaemonThread.java:39)
    at constxiong.concurrency.a008.TestDaemonThread.main(TestDaemonThread.java:11)
t : 非守護線程 , 執行次數 : 1
t : 非守護線程 , 執行次數 : 2
t : 非守護線程 , 執行次數 : 3
t : 非守護線程 , 執行次數 : 4
t : 非守護線程 , 執行次數 : 5
t : 非守護線程 , 執行次數 : 6
t : 非守護線程 , 執行次數 : 7
t : 非守護線程 , 執行次數 : 8
t : 非守護線程 , 執行次數 : 9
t : 非守護線程 , 執行次數 : 10

 


 


 

所有資源資源匯總於公眾號



 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM