在 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. sqlserver 临时表、表变量、CTE的比较

    原文地址:  sqlserver 临时表.表变量.CTE的比较 1.临时表 1.1 临时表包括:以#开头的局部临时表,以##开头的全局临时表. 1.2 存储 不管是局部临时表,还是全局临时表,都会放存 ...

  2. RocketMQ logback使用实践

    logback_broker.xml <?xml version="1.0" encoding="UTF-8"?> <!-- Licensed ...

  3. go语言之进阶篇定时器停止

    1.定时器停止 示例: package main import ( "fmt" "time" ) func main() { timer := time.New ...

  4. 第三章 Typescript 基本数据类型

    Typescript 基本数据类型 一.基本数据类型 Boolean Number String Array Tuple Enum Any Void Null 和 Undefined Never 二. ...

  5. .NET开发过程中的全文索引使用技巧之Solr(转)

       前言:相信许多人都听说过.net开发过程中基于Lucene.net实现的全文索引,而Solr是一个高性能,基于Lucene的全文搜索服务器.同时对其进行了扩展,提供了比Lucene更为丰富的查询 ...

  6. Recover Binary Search Tree leetcode java

    题目: Two elements of a binary search tree (BST) are swapped by mistake. Recover the tree without chan ...

  7. jquery中对 iframe的操作

    我们先看一下 JQUERY中的对像 contents() 的帮助文件 contents() 概述 查找匹配元素内部所有的子节点(包括文本节点).如果元素是一个iframe,则查找文档内容 示例 描述: ...

  8. 【Scala】Scala-循环与遍历

    Scala-循环与遍历 scala for 1000_百度搜索 Scala 2.8的for表达式:性能与运行顺序的改进 - 51CTO.COM scala List集合的用法 - CSDN博客

  9. AAAI 2018 论文 | 蚂蚁金服公开最新基于笔画的中文词向量算法

    AAAI 2018 论文 | 蚂蚁金服公开最新基于笔画的中文词向量算法 2018-01-18 16:13蚂蚁金服/雾霾/人工智能 导读:词向量算法是自然语言处理领域的基础算法,在序列标注.问答系统和机 ...

  10. 2017 年度码云新增项目排行榜 TOP 50,为它们打“call”

    2017 年度码云新增项目排行榜 TOP 50 正式出炉 !2017 结束了,我们来关注一下这一年里码云上新增的最热门的开源项目吧.此榜单根据 2017 年在码云上新增开源项目的 Watch.Star ...