Java中的Daemon線程--守護線程

守護線程

        學習的過程中偶然發現Java中居然也有守護線程這東西,感覺十分好奇,網上查閱一些資料做一些整理

加深自己的記憶,同時也方便日後的再學習。好記性不如爛博客!

        JVM中存在兩種線程:用戶線程守護線程

        所謂的守護線程,是指用戶程序在運行的時候後臺提供的一種通用服務的線程,比如用於垃圾回收的

垃圾回收線程。這類線程並不是用戶線程不可或缺的部分,只是用於提供服務的"服務線程"。

        基於這個特點,當虛擬機中的用戶線程全部退出運行時,守護線程沒有服務的對象後,JVM也就退出了。

        這點JDK源碼中的介紹已經說明這一點了。

* 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.
     即:當線程中只剩下守護線程時JVM就會退出,反之還有任意一個用戶線程在,JVM都不會退出。
         

        下面筆者用一個實際例子來驗證下上述論點。

package com.al;

import java.util.Scanner;

public class DaemonRunner implements Runnable {
    public void run() {
        while (true) {
            for (int i = 1; i <= 3; i++) {

                System.out.println("守護線程:"+i);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    public static void main(String[] args) {
    	 Thread daemonThread = new Thread(new DaemonRunner());
         // 設置爲守護進程
         daemonThread.setDaemon(true);
         daemonThread.start();
         System.out.println("isDaemon = " + daemonThread.isDaemon());
         Scanner scanner = new Scanner(System.in);
         // 接受輸入,使程序在此停頓,一旦接受到用戶輸入,main線程結束,JVM退出!
         scanner.next();  

         //AddShutdownHook方法增加JVM停止時要做處理事件:

         //當JVM退出時,打印JVM Exit語句.
         Runtime.getRuntime().addShutdownHook(new Thread(){
               @Override
             public void run() {
                 // TODO Auto-generated method stub
             System.out.println("JVM Exit!");
             }
           });
	}
}
            我們如何開始一個自定義的守護進程呢?正如上述代碼一樣,答案很簡單,就是在Thread.start()

  方法之前使用setDaemon(true)方法,通過此方法將Thread類中的boolean daemon=true;JVM就會將

 該線程歸爲守護線程。而且必須注意的是根據JDK源碼的解釋,該方法必須在start方法之前調用。

* <p> This method must be invoked before the thread is started.
            根據上述論點以及程序的邏輯,我們知道在我們向控制檯輸入後main線程就應該結束,從而導致

JVM退出,守護線程結束,不在打印相關語句。直接看輸出結果.

                           

             若想更加直觀的看到該情況,可以使用JDK自帶的工具jvisualvm.exe(bin目錄下)查看,下圖

     是筆者的查看情況

         

              也可以使用命令行下的jstack命令:

       

       

         該命令下可以看出有哪些守護線程,哪些用戶線程了。

         說完了守護線程如何產生和特點,下面簡要的談談使用守護線程應該注意的地方。

            1、thread.setDaemon(true)必須在thread.start()之前設置,否則會跑出一個異常。你不能把正在運行

                   的常規線程設置爲守護線程。 

            2、在守護線程中產生的線程也是守護線程。(這點讀者可結合工具自己驗證)

            3、我們自己產生的守護線程應該避免訪問一些類似於文件、數據庫等固有資源,因爲由於JVM沒有用戶

                 線程之後,守護線程會馬上終止。

      總結就到這個地方,筆者從沒使用過java中的Daemon線程,上述總結也參照了一些網上的資源加之自己的

 理解,不當之處希望指出。


By Kiritor


發佈了178 篇原創文章 · 獲贊 42 · 訪問量 91萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章