zoukankan      html  css  js  c++  java
  • 关于java线程的daemon的认识

    在 JAVA中的CountDownLatch、CyclicBarrier、Semaphore的简单测试 这文章里说到了线程的daemon问题,特写一篇来分析一下。

    上代码:

     1 package com.yzl.dubbo;
     2 
     3 import java.util.concurrent.TimeUnit;
     4 
     5 /**
     6  * java Thread的daemon属性测试
     7  * 结论:
     8  *       1、当虚拟机不存在daemon==false的线程时,虚拟机将会自动退出
     9  *    2、当虚拟机退出时,daemon里的finally代码不一定会执行完全(可能执行到一半就被强制干掉了)
    10  * @author yangzhilong
    11  *
    12  */
    13 public class Daemon {
    14 
    15     public static void main(String[] args) {
    16         Thread thread = new Thread(new DaemonRunner(), "daemon");
    17         //当虚拟机不存在daemon==false的线程时,虚拟机将会自动退出
    18         //mian线程属于false
    19         //不对这个属性进行设置的线程也是false
    20 //        thread.setDaemon(false);
    21         thread.setDaemon(true);
    22         thread.start();
    23     }
    24 
    25     static class DaemonRunner implements Runnable {
    26          @Override
    27         public void run() {
    28             for (int i = 0; i < 10; i++) {
    29                 try {
    30                     System.out.println("run ........");
    31                     TimeUnit.SECONDS.sleep(5);
    32                     System.out.println("end run......");
    33                 } catch (Exception e) {
    34                 } finally {
    35                     System.out.println("finally is runing。。。。");
    36                 }
    37             }
    38         }
    39     }
    40 }

    注释掉20行,放开21行的运行结果如下:

    run ........

    注释掉21行,放开20行的运行结果如下:

    run ........
    end run......
    finally is runing。。。。
    run ........
    end run......
    finally is runing。。。。
    run ........
    end run......
    finally is runing。。。。
    run ........
    end run......
    finally is runing。。。。
    run ........
    end run......
    finally is runing。。。。
    run ........
    end run......
    finally is runing。。。。
    run ........
    end run......
    finally is runing。。。。
    run ........
    end run......
    finally is runing。。。。
    run ........
    end run......
    finally is runing。。。。
    run ........
    end run......
    finally is runing。。。。

    我们来看看Thread的构造函数里的核心源码:

     1 private void init(ThreadGroup g, Runnable target, String name,
     2                       long stackSize, AccessControlContext acc) {
     3         if (name == null) {
     4             throw new NullPointerException("name cannot be null");
     5         }
     6 
     7         this.name = name;
     8 
     9         Thread parent = currentThread();
    10         SecurityManager security = System.getSecurityManager();
    11         if (g == null) {
    12             /* Determine if it's an applet or not */
    13 
    14             /* If there is a security manager, ask the security manager
    15                what to do. */
    16             if (security != null) {
    17                 g = security.getThreadGroup();
    18             }
    19 
    20             /* If the security doesn't have a strong opinion of the matter
    21                use the parent thread group. */
    22             if (g == null) {
    23                 g = parent.getThreadGroup();
    24             }
    25         }
    26 
    27         /* checkAccess regardless of whether or not threadgroup is
    28            explicitly passed in. */
    29         g.checkAccess();
    30 
    31         /*
    32          * Do we have the required permissions?
    33          */
    34         if (security != null) {
    35             if (isCCLOverridden(getClass())) {
    36                 security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
    37             }
    38         }
    39 
    40         g.addUnstarted();
    41 
    42         this.group = g;
    43         this.daemon = parent.isDaemon();
    44         this.priority = parent.getPriority();
    45         if (security == null || isCCLOverridden(parent.getClass()))
    46             this.contextClassLoader = parent.getContextClassLoader();
    47         else
    48             this.contextClassLoader = parent.contextClassLoader;
    49         this.inheritedAccessControlContext =
    50                 acc != null ? acc : AccessController.getContext();
    51         this.target = target;
    52         setPriority(priority);
    53         if (parent.inheritableThreadLocals != null)
    54             this.inheritableThreadLocals =
    55                 ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
    56         /* Stash the specified stack size in case the VM cares */
    57         this.stackSize = stackSize;
    58 
    59         /* Set thread ID */
    60         tid = nextThreadID();
    61     }

    被new出来的thread如果没有特别设置它的daemon属性,那它的daemon将和创建它的线程的daemon相同,Junit线程是daemon=true(后台线程),所以new出来的线程也是后台线程,当虚拟机中不存在daemon==false的线程后,虚拟机将会自动退出。

  • 相关阅读:
    工厂模式
    日历控件激发的事件(在呈现日时激发)
    在HTML页面里调用CS页面里的全局变量.
    DbDataAdapter填充(Fill)DataSet的情况
    IDataAdapter 接口
    一些HTML的知识!
    HTML页面里给DataGrid控件添加项!
    如何在网页中每小时更新一次数据?
    在windows下编译objectc语言
    Android牟利之道(四)如何推广你的产品,即你的APP
  • 原文地址:https://www.cnblogs.com/yangzhilong/p/6840791.html
Copyright © 2011-2022 走看看