Java 守护线程

在 Java 并发编程实践或看涉及到 Java 并发相关的代码时,经常会遇到一些线程(比如做 metrics 统计的线程等)会通过 setDaemon()
方法设置将该线程的 daemon 变量设置为 True,也就是将这个线程设置为了 守护线程(daemon thread)
,那么什么是守护线程呢?或者说守护线程与非守护线程(普通线程)的区别在什么地方呢?这个就是本文主要讲述的内容。

守护线程

一般来说,Java 中的线程可以分为两种:守护线程和普通线程。在 JVM 刚启动时,它创建的所有线程,除了主线程(main thread)外,其他的线程都是守护线程(比如:垃圾收集器、以及其他执行辅助操作的线程)。

当创建一个新线程时,新线程将会继承它线程的守护状态,默认情况下,主线程创建的所有线程都是普通线程。

什么情况下会需要守护线程呢?一般情况下是,当我们希望创建一个线程来执行一些辅助的工作,但是又不希望这个线程阻碍 JVM 的关闭,在这种情况下,我们就需要使用守护线程了。

守护线程的作用

守护线程与普通线程唯一的区别是:当线程退出时,JVM 会检查其他正在运行的线程,如果这些线程都是守护线程,那么 JVM 会正常退出操作,但是如果有普通线程还在运行,JVM 是不会执行退出操作的。当 JVM 退出时,所有仍然存在的守护线程都将被抛弃,既不会执行 finally 部分的代码,也不会执行 stack unwound 操作,JVM 会直接退出。

When the JVM halts any remaining daemon threads are abandoned:

 1. finally blocks are not executed,
 2. stacks are not unwound - the JVM just exits.

下面有个小示例,来自 What is a daemon thread in Java?
,代码如下:

public class DaemonTest{

    public static void main(String[] args){
        new WorkerThread().start();

        try {
            Thread.sleep(7500);
        } catch (InterruptedException e) {
            // handle here exception
        }

        System.out.println("Main Thread ending");
    }

}

class WorkerThreadextends Thread{

    public WorkerThread(){
        // When false, (i.e. when it's a user thread), the Worker thread continues to run.
        // When true, (i.e. when it's a daemon thread), the Worker thread terminates when the main thread terminates.
        setDaemon(false);
    }

    public void run(){
        int count = 0;

        while (true) {
            System.out.println("Hello from Worker " + count++);

            try {
                sleep(5000);
            } catch (InterruptedException e) {
                // handle exception here
            }
        }
    }
}

当为普通线程时,输出如下:

Hello from Worker 0
Hello from Worker 1
Main Thread ending
Hello from Worker 2
Hello from Worker 3
Hello from Worker 4
Hello from Worker 5
....

也就是说,此时即使主线程执行完了,JVM 也会等待 WorkerThread 执行完毕才会退出,而如果将该线程设置守护线程的话,输出如下:

Hello from Worker 0
Hello from Worker 1
Main Thread ending

在 main 线程执行完毕后,JVM 进程就退出了,不会 care WorkerThread 线程是否执行完毕。

参考:

  • What is a daemon thread in Java?
    ;
  • 《Java 并发编程实战》

原文 

http://matt33.com/2018/07/07/java-daemon-thread/

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » Java 守护线程

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址