多线程--守护线程

       守护线程是一类比较特殊的线程,一般用于处理一些后台操作,比如 JDK 的垃圾回收线程,接下来我们来探讨一下这个问题?

要理解守护线程之前,就必须搞清楚一个特别重要的问题: JVM 程序在什么情况下退出?

The Java Virtual Machine exits when the only threads running are all daemon threads .

这句话来自于 JDK 的官方文档,当然这句话指的是正常退出的情况, 而不是调用了 System,.exit() 方法, 通过这句话的描述,我们不难发现,在正常情况下,若 JVM 中没有一个非守护线程, 则 JVM 的进程会退出.

通过一个简单的程序来认识守护线程

public class DeamonThread {


    public static void main(String[] args) throws InterruptedException {
        //1 main 线程开始
        Thread thread = new Thread(() -> {
            while (true) {
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        //② 将thread 设置为守护线程
        //thread.setDaemon(true);

        //3 启动线程
        thread.start();

        Thread.sleep(2_000L);
        System.out.println("Main thread finished lifecycle");
        //4 结束线程
    }

}

       上面的代码中存在俩个线程,一个是由 JVM 启动的 main 线程,另外一个则是我们自己创建自己的线程 Thread, 运行 main 方法,你会发现 JVM 进程永远不会退出,即使 main 线程正常结束了自己的生命周期( main 线程的生命周期是 1-4之间那段代码),原因就是因为在 JVM 进程中还存在一个非守护线程在运行。

       如果打开了 ② 注释 ,通过setDaemon(true)方法将 thread 设置为了守护线程, 那么main 进程结束生命周期后, JVM 也会随之退出运行,当然 thread 线程也会结束。

注意:

  1. 守护线程的方法很简单,调用setDaemon方法即可,true代表守护线程,false代表正常线程
  2. 线程是否为守护线程与父线程有很大的关系,如果父线程是正常线程,则子类也是正常线程,反之亦然,如果你想修改它的特性则可以借助 setDaemon 方法, isDaemon 方法判断该线程是不是守护线程
  3. setDaemon 方法只在线程启动之前设置才能生效,如果一个线程一经死亡,那么再设置setDaemon则会抛出 IllegalThreadStateException 异常

守护线程的作用

       如果 JVM 进程中没有一个非守护线程,那么 JVM 会退出,也就是说守护线程具备自动结束生命周期的特性,而非守护线程则不具备这个特点,试想一下如果 JVM 进程的垃圾回收线程是一个非守护的线程,如果main方法完成了工作,则 JVM 无法退出,因为垃圾回收装置还在正常的工作。

      守护线程经常用作与执行一些后台任务,因此有时它也被称为后台线程,当你希望关闭某些线程的时候,或者退出 JVM 进程的时候,一些线程能够自动关闭,此时你就可以考虑使用守护线程来完成你的工作。

来源于<<java高并发编程详解>>

猜你喜欢

转载自blog.csdn.net/qq_40646143/article/details/93739053