守护线程

守护线程

        学习的过程中偶然发现Java中居然也有守护线程这东西,感觉十分好奇,网上查阅一些资料做一些整理

加深自己的记忆,同时也方便日后的再学习。好记性不如烂博客!

        JVM中存在两种线程:用户线程守护线程

        所谓的守护线程,是指用户程序在运行的时候后台提供的一种通用服务的线程,比如用于垃圾回收的

垃圾回收线程。这类线程并不是用户线程不可或缺的部分,只是用于提供服务的"服务线程"。

        基于这个特点,当虚拟机中的用户线程全部退出运行时,守护线程没有服务的对象后,JVM也就退出了。

        这点JDK源码中的介绍已经说明这一点了。

[plain]  view plain  copy
  1. * Marks this thread as either a {@linkplain #isDaemon daemon} thread  
  2.      * or a user thread. The Java Virtual Machine exits when the only  
  3.      * threads running are all daemon threads.  
     即: 当线程中只剩下守护线程时JVM就会退出,反之还有任意一个用户线程在,JVM都不会退出。
          

        下面笔者用一个实际例子来验证下上述论点。

[java]  view plain  copy
  1. package com.al;  
  2.   
  3. import java.util.Scanner;  
  4.   
  5. public class DaemonRunner implements Runnable {  
  6.     public void run() {  
  7.         while (true) {  
  8.             for (int i = 1; i <= 3; i++) {  
  9.   
  10.                 System.out.println("守护线程:"+i);  
  11.                 try {  
  12.                     Thread.sleep(1000);  
  13.                 } catch (InterruptedException e) {  
  14.                     e.printStackTrace();  
  15.                 }  
  16.             }  
  17.         }  
  18.     }  
  19.       
  20.     public static void main(String[] args) {  
  21.          Thread daemonThread = new Thread(new DaemonRunner());  
  22.          // 设置为守护进程  
  23.          daemonThread.setDaemon(true);  
  24.          daemonThread.start();  
  25.          System.out.println("isDaemon = " + daemonThread.isDaemon());  
  26.          Scanner scanner = new Scanner(System.in);  
  27.          // 接受输入,使程序在此停顿,一旦接受到用户输入,main线程结束,JVM退出!  
  28.          scanner.next();    
  29.   
  30.          //AddShutdownHook方法增加JVM停止时要做处理事件:  
  31.   
  32.          //当JVM退出时,打印JVM Exit语句.  
  33.          Runtime.getRuntime().addShutdownHook(new Thread(){  
  34.                @Override  
  35.              public void run() {  
  36.                  // TODO Auto-generated method stub  
  37.              System.out.println("JVM Exit!");  
  38.              }  
  39.            });  
  40.     }  
  41. }  
            我们如何开始一个自定义的守护进程呢?正如上述代码一样,答案很简单,就是在Thread.start()

  方法之前使用setDaemon(true)方法,通过此方法将Thread类中的boolean daemon=true;JVM就会将

 该线程归为守护线程。而且必须注意的是根据JDK源码的解释,该方法必须在start方法之前调用。

[plain]  view plain  copy
  1. * <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线程,上述总结也参照了一些网上的资源加之自己的

 理解,不当之处希望指出。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值