志玲姐姐已經找到了自己的守護天使,你呢?

Java極客技術發表於2019-08-04

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

什麼是守護執行緒

jAVA提供了兩種執行緒:守護執行緒和使用者執行緒,那麼什麼是守護執行緒呢?

守護執行緒又被稱之為“服務程式”, “精靈執行緒”或者是“後臺執行緒”,是指在程式執行的時候在後臺提供一種通用服務的執行緒。

這種執行緒並不屬於程式設計中不可或缺的部分。我們通俗一點說,任何一個守護執行緒都是整個JVM中所有的非守護執行緒的一個“保姆”。

 

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

但是我們要注意一點,一個執行緒預設不是守護執行緒。我們可以用一個例子來證明一下:

請看下面的Demo

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來進行服務,比如讀寫操作或者計算邏輯。

以上就是我所介紹的守護執行緒,你瞭解了麼?

關注公眾號,大家可以在公眾號後臺回覆“部落格園”,免費獲得作者 Java 知識體系/面試必看資料。

Java 極客技術公眾號,是由一群熱愛 Java 開發的技術人組建成立,專注分享原創、高質量的 Java 文章。如果您覺得我們的文章還不錯,請幫忙讚賞、在看、轉發支援,鼓勵我們分享出更好的文章。

相關文章