zoukankan      html  css  js  c++  java
  • 【转】关于Java的Daemon线程的理解

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

    关于Java的Daemon线程的理解

    网上对Java的Daemon线程的说法很多,看的人头晕。

    所以自己就来总结一下:

    Java语言自己可以创建两种进程“用户线程”和“守护线程”

    用户线程:就是我们平时创建的普通线程.

    守护线程:主要是用来服务用户线程.

    那么如何来区分这两种线程呢?

    其实在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,这些线程我们不用考虑).

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

    如果没有退出的话,当然就不会打印了.

    验证结果:

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

  • 相关阅读:
    WCF开发笔记 高版本.Net的坑
    Net Start可以加载驱动
    解决:Windows 2008远程黑屏问题
    Visual Studio 解决方案版本从v12-->v14
    Visual Studio 使用之禁用/启用模板警告
    Windows 10 常用的快捷键及常用指令
    git
    Socket通信原理 很好
    java集合
    JavaEE简介
  • 原文地址:https://www.cnblogs.com/wlf-919874006/p/5286482.html
Copyright © 2011-2022 走看看