java中的daemon thread

java中有两种类型的thread,user threads 和 daemon threads。

User threads是高优先级的thread,JVM将会等待所有的User Threads运行完毕之后才会结束运行。

daemon threads是低优先级的thread,它的作用是为User Thread提供服务。 因为daemon threads的低优先级,并且仅为user thread提供服务,所以当所有的user thread都结束之后,JVM会自动退出,不管是否还有daemon threads在运行中。

因为这个特性,所以我们通常在daemon threads中处理无限循环的操作,因为这样不会影响user threads的运行。

daemon threads并不推荐使用在I/O操作中。

但是有些不当的操作也可能导致daemon threads阻塞JVM关闭,比如在daemon thread中调用join()方法。

我们看下怎么创建daemon thread:

public class DaemonThread extends Thread{

    public void  run(){
while(true){
log.info("Thread A run");
try {
log.info("Thread A is daemon {}" ,Thread.currentThread().isDaemon());
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} public static void main(String[] args) throws InterruptedException {
DaemonThread daemonThread = new DaemonThread();
daemonThread.setDaemon(true);
daemonThread.start();
}
}

创建 daemon thread很简单,只需要在创建之后,设置其daemon属性为true即可。

注意setDaemon(true)必须在thread start()之前执行,否则会抛出IllegalThreadStateException

上面的例子将会立刻退出。

如果我们将daemonThread.setDaemon(true);去掉,则因为user thread一直执行,JVM将会一直运行下去,不会退出。

这是在main中运行的情况,如果我们在一个@Test中运行,会发生什么现象呢?

public class DaemonThread extends Thread{

    public void  run(){
while(true){
log.info("Thread A run");
try {
log.info("Thread A is daemon {}" ,Thread.currentThread().isDaemon());
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} @Test
public void testDaemon() throws InterruptedException {
DaemonThread daemonThread = new DaemonThread();
daemonThread.start();
}
}

我们将main方法改成了@Test执行。执行之后我们会发现,不管是不是daemon thread, Test都会立刻结束。

再看一个daemon线程中启动一个user thread的情况:

public class DaemonBThread extends Thread{

    Thread worker = new Thread(()->{
while(true){
log.info("Thread B run");
log.info("Thread B is daemon {}",Thread.currentThread().isDaemon());
}
});
public void run(){
log.info("Thread A run");
worker.start();
} public static void main(String[] args) {
DaemonBThread daemonThread = new DaemonBThread();
daemonThread.setDaemon(true);
daemonThread.start();
}
}

这个例子中,daemonThread启动了一个user thread,运行之后我们会发现,即使有user thread正在运行,JVM也会立刻结束执行。

本文的例子可以参考https://github.com/ddean2009/learn-java-concurrency/tree/master/DaemonThread

更多教程请参考 flydean的博客

java中的daemon thread的更多相关文章

  1. 怎么在java中关闭一个thread

    怎么在java中关闭一个thread 我们经常需要在java中用到thread,我们知道thread有一个start()方法可以开启一个线程.那么怎么关闭这个线程呢? 有人会说可以用Thread.st ...

  2. JAVA - 守护线程(Daemon Thread)

    转载自:http://www.cnblogs.com/luochengor/archive/2011/08/11/2134818.html 在Java中有两类线程:用户线程 (User Thread) ...

  3. Java中Runnable和Thread的区别

    在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口:Thread类是在java.lang包中定义的.一个类只要继承了Thread类同时覆写了本类中的run() ...

  4. Java中的线程Thread总结

    首先来看一张图,下面这张图很清晰的说明了线程的状态与Thread中的各个方法之间的关系,很经典的! 在Java中创建线程有两种方法:使用Thread类和使用Runnable接口. 要注意的是Threa ...

  5. Java中的线程Thread方法之---interrupt()

    前几篇都介绍了Thread中的几个方法,相信大家都发现一个相似点,那就是sleep,join,wait这样的阻塞方法都必须捕获一个InterruptedException异常,顾名思义就是一个线程中断 ...

  6. Java中的线程Thread方法之---stop()

    搞过Java线程的人都知道,stop这个方法是臭名昭著了,早就被弃用了,但是现在任然有很多钟情与他的人,永远都放不下他,因为从他的字面意思上我们可以知道他貌似可以停止一个线程,这个需求是每个搞线程开发 ...

  7. Java中Runnable和Thread

    java中有两种实现多线程的方式:一种是继承Thread类,一种是实现Runnable接口. 1.java启动线程为什么使用start函数呢? 在JDK的安装路径下,src.zip是全部的java源程 ...

  8. Java中Runnable和Thread的区别(转)

    http://developer.51cto.com/art/201203/321042.htm 第一种方式:使用Runnable接口创建线程 第二种方式:直接继承Thread类创建对象 使用Runn ...

  9. Java中的线程Thread方法之---suspend()和resume()

    前篇说到了Thread中的join方法,这一篇我们就来介绍一下suspend()和resume()方法,从字面意义上可以了解到这两个方法是一对的,suspend()方法就是将一个线程挂起(暂停),re ...

随机推荐

  1. CSS超链接样式,去除下划线等

    控制超链接样式 链接的四种状态: a:link - 普通的.未被访问的链接 a:visited - 用户已访问的链接 a:hover - 鼠标指针位于链接的上方 a:active - 链接被点击的时刻 ...

  2. touch方向锁定

    <!DOCTYPE html> <html> <head> <meta name="viewport" content="wid ...

  3. Mongo日期

    当通过mongo shell来插入日期类型数据时,使用new Date()和使用Date()是不一样的: > db.tianyc04.insert({mark:, mark_time:new D ...

  4. javascript入门 之 bind() (二)

    <!DOCTYPE html> <HTML> <HEAD> <script type="text/javascript" src=&quo ...

  5. Python设计模式(9)-外观模式

    # /*外观模式:为外界调用提供一个统一的接口,把其他类中需要用到的方法提取# * 出来,由外观类进行调用.然后在调用段实例化外观类,以间接调用需要的# * 方法.这种方式和代理模式有异曲同工之妙.然 ...

  6. AJ学IOS(32)UI之Quartz2D矩阵操作和图片剪切

    AJ分享,必须精品 矩阵操作 矩阵操作:(旋转,缩放,平移) 通过矩阵操作,把画出来的东西进行形变 旋转操作 方法:CGContextRotateCTM(<#CGContextRef c#> ...

  7. 假的数论gcd,真的记忆化搜索(Codeforce 1070- A. Find a Number)

    题目链接: 原题:http://codeforces.com/problemset/problem/1070/A 翻译过的训练题:https://vjudge.net/contest/361183#p ...

  8. 第三章:shell变量知识进阶

    特殊变量:位置变量大于9的时候,需要加上(),例如$(10)$*获取脚本的所有参数,如果不加""和$@是一样的效果,如果加上"",则表示所有参数组成一个字符串$ ...

  9. shell 脚本常用调试方法

    曾经我刚开始学习 shell 脚本时,除了知道用 echo 输出一些信息外,并不知道其他方法,仅仅依赖 echo 来查找错误,比较难调试且过程繁琐.效率低下.本文介绍下我常用的一些 shell 脚本调 ...

  10. DataGridView编辑状态自动提交

    在使用bindingSource.bindingNavigator+DataGridView修改时会发现,当你需要保存修改过后的内容,必须将光标指向另外一行,DataGridView才会将编辑过后的数 ...