【转】关于Java的Daemon线程的理解

原文地址:http://www.cnblogs.com/ChrisWang/archive/2009/11/28/1612815.htmlhtml

关于Java的Daemon线程的理解

网上对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)
 
获得结果以下:
thread_dump 
thread_dump2 
 

咱们会看到当前JVM进程中跑着不少线程,可是只有main线程是用户线程,其余线程要不是daemon线程(如Low Memory Detector或Thread-0),要不就是虚拟机内部线程(如VM Thread 和VM Periodic Task Thread,这些线程咱们不用考虑).code

所以当用户线程main线程退出时(在本程序中,在控制台输入一个字符而后回车),若是JVM确实退出了的话,会调用ShutDownHook在控制台上打印“JVM Exit!.”htm

若是没有退出的话,固然就不会打印了.

验证结果:

控制台成功打印“JVM Exit!”,JVM退出!

相关文章
相关标签/搜索