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

上代码:

 package com.yzl.dubbo;

 import java.util.concurrent.TimeUnit;

 /**
* java Thread的daemon属性测试
* 结论:
* 1、当虚拟机不存在daemon==false的线程时,虚拟机将会自动退出
* 2、当虚拟机退出时,daemon里的finally代码不一定会执行完全(可能执行到一半就被强制干掉了)
* @author yangzhilong
*
*/
public class Daemon { public static void main(String[] args) {
Thread thread = new Thread(new DaemonRunner(), "daemon");
//当虚拟机不存在daemon==false的线程时,虚拟机将会自动退出
//mian线程属于false
//不对这个属性进行设置的线程也是false
// thread.setDaemon(false);
thread.setDaemon(true);
thread.start();
} static class DaemonRunner implements Runnable {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
try {
System.out.println("run ........");
TimeUnit.SECONDS.sleep(5);
System.out.println("end run......");
} catch (Exception e) {
} finally {
System.out.println("finally is runing。。。。");
}
}
}
}
}

注释掉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的构造函数里的核心源码:

 private void init(ThreadGroup g, Runnable target, String name,
long stackSize, AccessControlContext acc) {
if (name == null) {
throw new NullPointerException("name cannot be null");
} this.name = name; Thread parent = currentThread();
SecurityManager security = System.getSecurityManager();
if (g == null) {
/* Determine if it's an applet or not */ /* If there is a security manager, ask the security manager
what to do. */
if (security != null) {
g = security.getThreadGroup();
} /* If the security doesn't have a strong opinion of the matter
use the parent thread group. */
if (g == null) {
g = parent.getThreadGroup();
}
} /* checkAccess regardless of whether or not threadgroup is
explicitly passed in. */
g.checkAccess(); /*
* Do we have the required permissions?
*/
if (security != null) {
if (isCCLOverridden(getClass())) {
security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
}
} g.addUnstarted(); this.group = g;
this.daemon = parent.isDaemon();
this.priority = parent.getPriority();
if (security == null || isCCLOverridden(parent.getClass()))
this.contextClassLoader = parent.getContextClassLoader();
else
this.contextClassLoader = parent.contextClassLoader;
this.inheritedAccessControlContext =
acc != null ? acc : AccessController.getContext();
this.target = target;
setPriority(priority);
if (parent.inheritableThreadLocals != null)
this.inheritableThreadLocals =
ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
/* Stash the specified stack size in case the VM cares */
this.stackSize = stackSize; /* Set thread ID */
tid = nextThreadID();
}

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

关于java线程的daemon的认识的更多相关文章

  1. Java并发编程(三)后台线程(Daemon Thread)

    后台线程,守护线程(Daemon Thread) 所谓的后台线程,就是指这种线程并不属于程序中不可或缺的部分,因此当所有的非后台线程结束时,程序也就终止了,同时会杀死进程中的所有后台线程.通过setD ...

  2. Java 多线程(四)之守护线程(Daemon)

    目录 定义 如何创建 判断 注意事项 函数setDaemon(true)必须在 start() 函数之前使用. 守护线程中产生的线程也是守护线程: 测试 @ 定义 Java 中有两种线程: 一种是用户 ...

  3. java线程基础知识----java daemon线程

    java线程是一个运用很广泛的重点知识,我们很有必要了解java的daemon线程. 1.首先我们必须清楚的认识到java的线程分为两类: 用户线程和daemon线程 A. 用户线程: 用户线程可以简 ...

  4. Java 守护线程(Daemon) 例子

    当我们在Java中创建一个线程,缺省状态下它是一个User线程,如果该线程运行,JVM不会终结该程序.当一个线被标记为守护线程,JVM不会等待其结束,只要所有用户(User)线程都结束,JVM将终结程 ...

  5. java线程 - 多线程 - 守护线程

    1.多线程执行者/处理类 都是Runnable的实现类(如自定义类实现Runnable 或 java原生的Thread.FutureTask),但最后都必须封装成Thread线程类由Thread.st ...

  6. 怎样分析java线程堆栈日志

    注: 该文章的原文是由 Tae Jin Gu 编写,原文地址为 How to Analyze Java Thread Dumps 当有障碍,或者是一个基于 JAVA 的 WEB 应用运行的比预期慢的时 ...

  7. JAVA线程基础

    一.线程状态 由于参考的维度不一样,线程状态划分也不一样,我这里简单的分为5大类,并且会说明状态变迁的详细过程:

  8. Java线程与多线程教程

    本文由 ImportNew - liken 翻译自 Journaldev.   Java线程是执行某些任务的轻量级进程.Java通过Thread类提供多线程支持,应用可以创建并发执行的多个线程. 应用 ...

  9. Java线程池学习

    Java线程池学习 Executor框架简介 在Java 5之后,并发编程引入了一堆新的启动.调度和管理线程的API.Executor框架便是Java 5中引入的,其内部使用了线程池机制,它在java ...

随机推荐

  1. SVG 相关整理

    1. 中文参考手册: http://www.runoob.com/svg/svg-reference.html SVG HTML5 资源教程 http://www.html5tricks.com/ta ...

  2. Visual Studio提示“无法启动IIS Express Web服务器”的解决方法 vs调试显示无法显示此页面 ,vs调试浏览器白页

    有时,在使用Visual Studio运行ASP.NET项目时,会提示“无法启动IIS Express Web服务器”,无法运行,如图: 这一般出现在重装系统之后,或者项目是从别的电脑上复制过来的.解 ...

  3. pthread_once重塑singleton模式

    单件模式是非线程安全的: // Single threaded version class Foo { private Helper helper = null; public Helper getH ...

  4. 读书笔记,《Java8实战》第一章,为什么要关心 Java8

       开篇作者就提出,Java8所做的改变在许多方面比java历史上任何一次改变都深远.而且好消息是,这些改变会让你编辑程序来更容易,再也不用写类似类似于以前的swing中的事件处理函数的啰嗦代码了. ...

  5. 构建配置 defaultConfig signingConfigs buildTypes productFlavors dependencies

    测试项目位置:https://github.com/baiqiantao/FragmentTest.git 项目结构: project 目录的 build.gradle 文件 // Top-level ...

  6. Druid连接池简介和配置

    Druid是什么?有什么作用?  Druid首先是一个数据库连接池,但它不仅仅是一个数据库连接池,它还包含一个ProxyDriver,一系列内置的JDBC组件库,一个SQL Parser. Druid ...

  7. GDB 程序调试简单实践

    用了好久的GCC/G++ 却一直都没用过GDB调试过程序,有时程序不是非常大,一般有错,直接看编译器编译结果就几乎相同知道错在哪儿了,或者使用codeblocks单步调试,甚至回到windows以下调 ...

  8. 转:Logistic regression (逻辑回归) 概述

    Logistic regression (逻辑回归)是当前业界比较常用的机器学习方法,用于估计某种事物的可能性.比如某用户购买某商品的可能性,某病人患有某种疾病的可能性,以及某广告被用户点击的可能性等 ...

  9. 从数据库中取 datetime类型,界面展示 yyyy-MM-dd

    //处理提问时间,去掉时分秒 if(array!=null && array.size()>0){ for(int i=0;i<array.size();i++){ JSO ...

  10. (NGUI)UISprite 切换图集

    UISprite是可以使用代码动态切换图集的 using UnityEngine; using System.Collections; public class SpriteAtlasTest : M ...