Java線程和多線程(六)——守護線程

當我們在Java中創建線程的時候,這個線程在默認的情況下是一個用戶線程,並且,如果這個線程在運行,那麼JVM就不會終結這個應用。和用戶線程不同,當一個線程被標記爲守護線程的時候,JVM在用戶線程結束的時候,是不會持續等待守護線程結束的,而是直接結束程序,並且結束程序中相關的守護線程。

Thread.setDaemon(true)方法可以用來將線程置爲守護線程,參考下面的例子:

package com.sapphire.threads;

public class JavaDaemonThread {

    public static void main(String[] args) throws InterruptedException {
        Thread dt = new Thread(new DaemonThread(), "dt");
        dt.setDaemon(true);
        dt.start();
        //continue program
        Thread.sleep(30000);
        System.out.println("Finishing program");
    }

}

class DaemonThread implements Runnable{

    @Override
    public void run() {
        while(true){
            processSomething();
        }
    }

    private void processSomething() {
        try {
            System.out.println("Processing daemon thread");
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

當執行上面的程序時,JVM會包含main方法這個線程,而後在main方法中創建一個用戶線程,然後是變成了守護線程。當main函數結束的時候,程序就會結束,而且JVM也會同時關閉掉守護線程。

程序的輸出如下:

Processing daemon thread
Processing daemon thread
Processing daemon thread
Processing daemon thread
Processing daemon thread
Processing daemon thread
Finishing program

但是,如果我們沒有將線程置爲守護線程的話,程序就永遠都不會結束,就算main函數的線程執行完畢,程序仍然會繼續下去。

通常來說,我們創建一個守護線程爲了一些跟系統不那麼相關的功能。舉例來說,日誌線程或者監控系統資源狀態的線程等。

守護線程的配置必須在線程啓動之前,參考Javadoc

    /**
     * Marks this thread as either a {@linkplain #isDaemon daemon} thread
     * or a user thread. The Java Virtual Machine exits when the only
     * threads running are all daemon threads.
     *
     * <p> This method must be invoked before the thread is started.
     *
     * @param  on
     *         if {@code true}, marks this thread as a daemon thread
     *
     * @throws  IllegalThreadStateException
     *          if this thread is {@linkplain #isAlive alive}
     *
     * @throws  SecurityException
     *          if {@link #checkAccess} determines that the current
     *          thread cannot modify this thread
     */
    public final void setDaemon(boolean on) {
        checkAccess();
        if (isAlive()) {
            throw new IllegalThreadStateException();
        }
        daemon = on;
    }
發佈了44 篇原創文章 · 獲贊 24 · 訪問量 36萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章