多線程講解二: 守護線程 (讓你真正的理解守護線程)

其實很多人,對守護線程並不理解。主要原因是: 測試很不好測,有外界因素干擾。

 

所以這篇文章,只是讓你認識守護線程,理解守護線程,千萬不要糾結於爲什麼用@Test測試 和 用main方法測試。因爲你如果反過來用@Test用main來測,結果剛剛相反。至於爲什麼:1.@Test 的4版本不支持多線程   2.main方法本身就是jvm啓動的一個線程。沒有足夠理解多線程的時候,千萬不要想這個問題。記得只看結果,不看過程。

 

今天就用兩個例子,好好的扒一下 守護線程。

核心:當一個Java應用內只有守護線程時,Java虛擬機自然退出。

 

第一: 當沒有守護線程的時候會發生什麼 ?

首先先創建一個線程:

public class NotDaemonThread extends Thread {

    public NotDaemonThread(String name) {
        super(name);
    }

    @Override
    public void run() {
        try {
            sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        for (int i = 0; i < 20; i++) {
            System.out.println(Thread.currentThread().getName() + ": " + i);
        }
    }
}

然後我們來調用他: (這裏必須用@Test來測試

    @Test
    public void test() {
        NotDaemonThread thread1 = new NotDaemonThread("非守護線程 1");
        NotDaemonThread thread2 = new NotDaemonThread("非守護線程 2");

        thread1.start();
        thread2.start();

        for (int i = 0; i < 10; i++) {
            System.out.println("程序執行中" + i);
        }
        System.out.println("程序執行完畢");
    }

結果:證明了如果沒有守護線程,就不會等其他線程執行完畢之後,才停止程序。

程序執行中0
程序執行中1
程序執行中2
程序執行中3
程序執行中4
程序執行中5
程序執行中6
程序執行中7
程序執行中8
非守護線程 2: 0
非守護線程 1: 0
程序執行中9
程序執行完畢

 

第二:當有守護線程的時候

創建一個新線程,目前他是一個正常的線程,但是我準備將其做爲 守護線程

public class DaemonThread extends Thread {

    @Override
    public void run() {
        while (true) {
            try {
                sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName());
        }
    }
}

創建一個新線程,想象他是一個需要正常運行程序的線程,他必須執行完畢,程序才能停止

public class UseThread extends Thread {

    public UseThread(String name) {
        super(name);
    }

    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            try {
                sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + ": " + i);
        }
    }
}

測試代碼:

public class Test {

    /**
     * 當一個Java應用內只有守護線程時,Java虛擬機自然退出。
     * <p>
     * 守護線程其實挺難理解的: 上面那句話是核心。
     *
     * @throws InterruptedException
     */
    public static void main(String[] args) {
        DaemonThread daemonThread = new DaemonThread();
        Thread thread = new Thread(daemonThread, "守護線程");
        // 標記DaemonThread爲守護線程
        thread.setDaemon(true);
        thread.start();

        UseThread userThread = new UseThread("正在使用的線程");
        // 啓動我們要正常使用的線程
        userThread.start();


        System.out.println("主線程被銷燬");
    }
}

結果:程序最後的這句話已經打印,但是線程還是在執行中,當正在使用的線程執行到4,執行完畢之後,守護線程自動銷燬。

主線程被銷燬
守護線程
正在使用的線程: 0
守護線程
正在使用的線程: 1
守護線程
正在使用的線程: 2
守護線程
正在使用的線程: 3
守護線程
正在使用的線程: 4

 

 

最後再總結一下:

只要守護線程還在,其他線程都能正常運行。

其他線程全都運行完畢了,守護線程就自動銷燬。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章