线程类Thread的API接口分析系列之守护线程setDaemon

来源:互联网 发布:ubuntu 16.04更新源 编辑:程序博客网 时间:2024/06/02 11:30

对于java中的守护线程的概念一直了解的比较少,有时还会跟linux中的守护进程搞混淆。简单来说,设置守护线程的使用非常简单,但是原理还是有点小晦涩。先看源码

   /* Whether or not the thread is a daemon thread. */

   private boolean     daemon =false;

   public final void setDaemon(boolean on) {

       checkAccess();

       if (isAlive()) {

           throw new IllegalThreadStateException();

       }

       daemon = on;

}

--就源码而言,也非常简单,就是对Thread类的私有成员变量daemon设置为传入的参数,daemon默认初始值是false,也就是说如果创建线程而不调用setDaemon(true)来修改的话,创建的线程默认是非守护线程(用户线程)。那守护线程和用户线程的区别在哪里呢?我之前把linux操作系统的守护进程的概念直接代入,有点误导。实际上java的守护线程的概念跟linux有点类似,但是又不完全一样。守护线程创建后,该线程的控制权限和linux一样,不再属于前台,而是被虚拟机进行接管(就像linux的守护进程一样被操作系统所接管,跟创建出它的shell无关,当我们推出shell时,只要操作系统没挂掉,该进程依旧运行),java的虚拟机在这里充当了操作系统的角色,其实从“虚拟机”这个命名来说,也是有操作系统的概念的(只是它只管理java进程)。那么不同之处在于,守护线程在虚拟机中优先级比较低 ,另外守护线程它是服务虚拟机其他用户线程的,就相当仆人的角色。如果虚拟机中没有了用户线程,那么虚拟机将推迟,所有依赖于虚拟机的守护线程都被终止运行。就相当于linux操作系统挂掉了,所有守护进程也得终止。只是虚拟机会在用户线程不存在的情况下自动退出,而操作系统不会因为没有用户进程而挂掉。

用例子说话:(创建普通用户线程)

public class ThreadApiTest implementsRunnable {

 

        

         /**

         *多线程相关api测试

         *@author : zhengrf1

         *@date 创建时间:2017年3月7日下午4:43:15

         */

         publicstatic void main(String[] args) {

                   //TODO Auto-generated method stub

                   Threadtest = new Thread(new ThreadApiTest());

                   //test.setDaemon(true);

                   test.start();

                   try{

                            Thread.sleep(10000);

                   }catch (InterruptedException e) {

                            //TODO Auto-generated catch block

                            e.printStackTrace();

                   }

                   System.out.println(Thread.currentThread().getName()+"isend!");

         }

 

         /*@author : zhengrf1

          * @date 创建时间:2017年3月7日 下午4:46:48

          * @see java.lang.Runnable#run()

          */

         @Override

         publicvoid run() {

                   //TODO Auto-generated method stub

                   while(true){

                            System.out.println(Thread.currentThread().getName()+"isalive!");

                            try{

                                     Thread.sleep(1000);

                            }catch (InterruptedException e) {

                                     //TODO Auto-generated catch block

                                     e.printStackTrace();

                                     System.out.println(Thread.currentThread().isInterrupted());

                                     System.out.println(Thread.interrupted());

                            }

                   }

         }

 

}

 

--根据输出会发现,虚拟机在主线程结束后,因为还有一个用户线程不断循环,所以并没退出。把//test.setDaemon(true);注释取消后会发现虚拟机在主线程结束后不存在任何用户线程了,所以虚拟机停止运行,并且终止了所有依赖于虚拟机的守护线程。

0 0
原创粉丝点击