線程之守護線程

多線程一直是我們開發中最關注的一個點,因為在併發中,會有各種各樣的問題,但是這中多線程中的問題,又是我們需要去解決的, 之前看書看到過一點內容,也和大家分享一下關於守護線程的一些知識。

什麼是守護線程

JAVA提供了兩種線程:守護線程和用戶線程,那麼什麼是守護線程呢?

守護線程又被稱之為“服務進程”, “精靈線程”或者是“後臺線程”,是指在程序運行的時候在後臺提供一種通用服務的線程。 這種線程並不屬於程序設計中不可或缺的部分。我們通俗一點說,任何一個守護線程都是整個JVM中所有的非守護線程的一個“保姆”。

用戶線程和守護線程幾乎是一樣的,唯一的不同之處就是在於如果說用戶線程已經全部退出了運行,只剩下守護線程存在了,那麼JVM也就回相對應的 退出了,因為當所有的非守護線程結束的時候,沒有任何線程需要去被守護,那麼守護線程就沒工作可以繼續做了,那麼就說明程序是被終止了, 這時候所有的守護線程都會被“殺死”。也就是說,只要有任何一個非守護線程還處在運行當中的話,那麼守護線程就不會終止。

但是我們要注意一點,一個線程默認不是守護線程。

我們可以用一個例子來證明一下:

請看下面的Demo

123456789101112
public class DaemonThreadTest extends Thread {    public static void main(String[] args) {        DaemonThreadTest daemonThreadTest = new DaemonThreadTest("後臺線程");        System.out.println("是否是守護線程"+"---"+daemonThreadTest.isDaemon());    }    public DaemonThreadTest(String name){       super();    }}
線程之守護線程

結果就像圖中所示的,一個線程不是守護線程。

但是在JAVA語言中,守護線程一般都具有的優先級都是比較低的,他並非是只有JVM內部來提供的,用戶在編寫程序的時候也可以自己去設置守護 線程,例如,將一個用戶線程設置為守護線程的方法就是在調用start()方法的啟動線程之前調用對象的setDaemom(true)這個方法, 若將以上的參數設置為false的時候,則表示的是用戶進程模式,需要注意的是,當在一個守護線程中產生了其他的線程,那麼這些新產生的 線程默認會是守護線程,用戶線程也是如此,

我們看一下代碼實例

public class DaemonThreadTest2 extends Thread{    public void  run(){        System.out.println(Thread.currentThread().getName()+":begain");        try {            Thread.sleep(1000);        } catch (InterruptedException e) {            e.printStackTrace();        }        System.out.println(Thread.currentThread().getName()+":end");    }}class Test{    public static void main(String[] args) {        System.out.println("test1:begain");        DaemonThreadTest2 daemonThreadTest2 = new DaemonThreadTest2();        daemonThreadTest2.setDaemon(true);        daemonThreadTest2.start();        System.out.println("test1:end");    }}

大家可以簡單的想一下結果是什麼?

結果其實是這樣的

線程之守護線程

從運行的記過中我們也可以發現,沒有輸出Thread-0:end,那麼為什麼結果會是這種樣子的呢?

其實就是在啟動線程前,我們將其設置為守護線程了,當程序中只有守護線程存在的時候,JVM是可以退出的, 額就是說,當JVM中只有守護線程運行的時候,JVM會自動關閉。

因此,當test1方法在調用的結束後,main線程將會退出,這時候線程daemonThreadTest2還處於休眠狀態沒有運行結束,但是這個時候只有守護線程在 運行了,JVM關閉了,因此它就不會輸出“Thread-0:end”了。

守護線程的一個典型的例子就是垃圾回收器,只要JVM啟動,他就會一直運行,實時的區監控可以被回收的資源。

是用守護線程要注意幾點:

  • thread.setDaemon(true)必須在thread.start()之前設置,否則會跑出一個IllegalThreadStateException異常。你不能把正在運行的常規線程設置為守護線程。
  • 在Daemon線程中產生的新線程也是Daemon的。
  • 不要認為所有的應用都可以分配給Daemon來進行服務,比如讀寫操作或者計算邏輯。

以上就是我所介紹的守護線程,你瞭解了麼?


分享到:


相關文章: