1. 程式人生 > >守護執行緒與使用者執行緒

守護執行緒與使用者執行緒

使用者執行緒:我們平常建立的普通執行緒。

守護執行緒:用來服務於使用者執行緒;不需要上層邏輯介入。

通過一個栗子來區分一下它們與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就不會退出。

使用它需要注意些什麼? 

  1. thread.setDaemon(true)必須在thread.start()之前設定,否則會跑出一個IllegalThreadStateException異常。你不能把正在執行的常規執行緒設定為守護執行緒。

  2. 在Daemon執行緒中產生的新執行緒也是Daemon的。

  3. 守護執行緒不能用於去訪問固有資源,比如讀寫操作或者計算邏輯。因為它會在任何時候甚至在一個操作的中間發生中斷。

  4. Java自帶的多執行緒框架,比如ExecutorService,會將守護執行緒轉換為使用者執行緒,所以如果要使用後臺執行緒就不能用Java的執行緒池。

意義及應用場景

當主執行緒結束時,結束其餘的子執行緒(守護執行緒)自動關閉,就免去了還要繼續關閉子執行緒的麻煩。如:Java垃圾回收執行緒就是一個典型的守護執行緒;記憶體資源或者執行緒的管理,但是非守護執行緒也可以。

它的存在,必定有它的意義,只需在乎我們怎麼把它用到恰到好處。