原文地址:http://www.cnblogs.com/ChrisWang/archive/2009/11/28/1612815.htmlhtml
網上對Java的Daemon線程的說法不少,看的人頭暈。多線程
因此本身就來總結一下:ide
Java語言本身能夠建立兩種進程「用戶線程」和「守護線程」工具
用戶線程:就是咱們平時建立的普通線程.post
守護線程:主要是用來服務用戶線程.url
那麼如何來區分這兩種線程呢?spa
其實在JDK的文檔中已經說明的很清楚了:線程
* The Java Virtual Machine exits when the only threads running are all * daemon threads.
即:
當線程只剩下守護線程的時候,JVM就會退出.可是若是還有其餘的任意一個用戶線程還在,JVM就不會退出.
下面咱們用實驗來講明,當線程只剩下守護線程的時候,JVM就會退出.
代碼以下:
public class DaemonRunner implements Runnable { public void run() { while (true) { for (int i = 1; i <= 100; 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!"); } }); } }
當程序運行的時候,Daemon線程會不斷的在控制檯打印數字,而main線程是一個用戶線程因爲」scanner.next()」
等待用戶輸入,屬於阻塞了.此時JVM固然不會退出.
驗證步驟:
這個時候只要咱們肯定當前用戶線程只有一個,即只要main線程退出,而後檢查JVM是否真的退出了。
那麼咱們如何肯定當前的JVM虛擬機中的,當前的用戶線程和daemon有多少呢?
咱們能夠用JDK中自帶的查看堆棧工具jstack.
jstack 3308(即當前要探測的JVM進程的進程ID)
獲得結果以下:
咱們會看到當前JVM進程中跑着不少線程,可是隻有main線程是用戶線程,其餘線程要不是daemon線程(如Low Memory Detector或Thread-0),要不就是虛擬機內部線程(如VM Thread 和VM Periodic Task Thread,這些線程咱們不用考慮).code
所以當用戶線程main線程退出時(在本程序中,在控制檯輸入一個字符而後回車),若是JVM確實退出了的話,會調用ShutDownHook在控制檯上打印「JVM Exit!.」htm
若是沒有退出的話,固然就不會打印了.
驗證結果:
控制檯成功打印「JVM Exit!」,JVM退出!