2023-03-22  阅读(3)
原文作者:简单教程 原文地址:https://www.twle.cn/c/yufei/javatm/javatm-basic-executorservice.html

在这篇简短的文章中,我们将讲解下 Java 中的守护线程,看看它们可以做什么。我们还将解释守护线程和用户线程之间的区别。

守护线程和用户线程的区别

Java 提供了两种类型的线程: 守护线程用户线程

  • 用户线程 是高优先级线程。JVM 会在终止之前等待任何用户线程完成其任务。
  • 用户线程 是低优先级线程。其唯一作用是为用户线程提供服务。

由于守护线程的作用是为用户线程提供服务,并且仅在用户线程运行时才需要,因此一旦所有用户线程完成执行,JVM 就会终止。也就是说 守护线程不会阻止 JVM 退出

这也是为什么通常存在于守护线程中的无限循环不会导致问题,因为任何代码(包括 finally 块 )都不会在所有用户线程完成执行后执行。

这也是为什么我们并不推荐 在守护线程中执行 I/O 任务 。因为可能导致无法正确关闭资源。

但是,守护线程并不是 100% 不能阻止 JVM 退出的。守护线程中设计不良的代码可能会阻止 JVM 退出。例如,在正在运行的守护线程上调用Thread.join() 可以阻止应用程序的关闭。

守护线程能用来做什么?

常见的做法,就是将守护线程用于后台支持任务,比如垃圾回收、释放未使用对象的内存、从缓存中删除不需要的条目。

咦,按照这个解释,那么大多数 JVM 线程都是守护线程。

如何创建守护线程 ?

守护线程也是一个线程,因此它的创建和启动其实和普通线程没什么区别?

要将普通线程设置为守护线程,方法很简单,只需要调用 Thread.setDaemon() 方法即可。

例如下面这段代码,假设我们继承 Thread 类创建了一个新类 NewThread 。那么我们就可以创建这个类的实例并设置为守护线程

    NewThread daemonThread = new NewThread();
    daemonThread.setDaemon(true);
    daemonThread.start();

在 Java 语言中,线程的状态是自动继承的。任何线程都会继承创建它的线程的守护程序状态。怎么理解呢?

  1. 如果一个线程是普通线程( 用户线程) ,那么它创建的子线程默认也是普通线程( 用户线程 )。
  2. 如果一个线程是守护线程,那么它创建的子线程默认也是守护线程。

因此,我们可以推演出: 由于主线程是用户线程,因此在 main() 方法内创建的任何线程默认为用户线程。

需要注意的是调用 setDaemon() 方法的时机,该方法只能在创建 Thread 对象并且在启动线程前调用。在线程运行时尝试调用 setDaemon() 将抛出 IllegalThreadStateException 异常。

    @Test(expected = IllegalThreadStateException.class)
    public void whenSetDaemonWhileRunning_thenIllegalThreadStateException() {
        NewThread daemonThread = new NewThread();
        daemonThread.start();
        daemonThread.setDaemon(true);
    }

如何检查一个线程是守护线程还是用户线程?

检查一个线程是否是守护线程,可以简单地调用方法 isDaemon() ,如下代码所示

    @Test
    public void whenCallIsDaemon_thenCorrect() {
        NewThread daemonThread = new NewThread();
        NewThread userThread = new NewThread();
        daemonThread.setDaemon(true);
        daemonThread.start();
        userThread.start();
    
        assertTrue(daemonThread.isDaemon());
        assertFalse(userThread.isDaemon());
    }

后记

守护线程的概念是不是很简单?


Java 面试宝典是大明哥全力打造的 Java 精品面试题,它是一份靠谱、强大、详细、经典的 Java 后端面试宝典。它不仅仅只是一道道面试题,而是一套完整的 Java 知识体系,一套你 Java 知识点的扫盲贴。

它的内容包括:

  • 大厂真题:Java 面试宝典里面的题目都是最近几年的高频的大厂面试真题。
  • 原创内容:Java 面试宝典内容全部都是大明哥原创,内容全面且通俗易懂,回答部分可以直接作为面试回答内容。
  • 持续更新:一次购买,永久有效。大明哥会持续更新 3+ 年,累计更新 1000+,宝典会不断迭代更新,保证最新、最全面。
  • 覆盖全面:本宝典累计更新 1000+,从 Java 入门到 Java 架构的高频面试题,实现 360° 全覆盖。
  • 不止面试:内容包含面试题解析、内容详解、知识扩展,它不仅仅只是一份面试题,更是一套完整的 Java 知识体系。
  • 宝典详情:https://www.yuque.com/chenssy/sike-java/xvlo920axlp7sf4k
  • 宝典总览:https://www.yuque.com/chenssy/sike-java/yogsehzntzgp4ly1
  • 宝典进展:https://www.yuque.com/chenssy/sike-java/en9ned7loo47z5aw

目前 Java 面试宝典累计更新 400+ 道,总字数 42w+。大明哥还在持续更新中,下图是大明哥在 2024-12 月份的更新情况:

想了解详情的小伙伴,扫描下面二维码加大明哥微信【daming091】咨询

同时,大明哥也整理一套目前市面最常见的热点面试题。微信搜[大明哥聊 Java]或扫描下方二维码关注大明哥的原创公众号[大明哥聊 Java] ,回复【面试题】 即可免费领取。

阅读全文