← 每日面试题 学习看板

什么是守护线程,和普通线程有什么区别?

面试题/00java/02Java 并发编程/01线程基础概念/什么是守护线程,和普通线程有什么区别?.md

面试记录 2026-09-29

题目:什么是守护线程,和普通线程有什么区别?

难度:low

标签:java/thread, difficulty/low

评分:⭐☆☆☆☆(1/5)

我的回答

守护线程指的是更隐性的一个低优先级线程,它会在其他线程结束之后做恢复使用,恢复保护其他线程。我印象中在 Docker 中有类似的东西,守护线程,然后 ZAM 中也有。

守护线程执行的时候需要在 Java 中守护线程执行的时候需要做设置,把当前线程设置为,把一个线程设置为守护线程。守护线程的区别,我没什么印象了。

点评

优点:

不足:

补充:

完整讲解

第一部分:知识重点剖析

核心考点定位:区分 Java 中"用户线程"和"守护线程"的生命周期语义,考察对 JVM 退出条件的理解。

知识点拆解:

  1. 底层原理:Thread 有一个 daemon 标志位(setDaemon(true) 设置),JVM 退出判断时只看用户线程数,守护线程不参与计数
  2. 设计权衡:守护线程没有"善后机会"(无 finally 保证执行),因此只适合"服务型"任务,不适合"必须完成"的业务
  3. 工程实践:GC、JIT、Finalizer、Reference Handler 等 JVM 内部线程都是守护线程;应用层的日志 flush、心跳上报通常也设为守护

第二部分:考察方向与延伸递进

考察方向:

延伸递进面试题:

  1. 守护线程里的 finally 一定会执行吗?
  1. 如何在守护线程里做收尾工作?
  1. 守护线程可以创建子线程吗?子线程的属性是什么?

第三部分:面试者参考回答(300-600 字口语化)

面试官您好,Java 里的线程分用户线程和守护线程两类,通过 thread.setDaemon(true) 把线程标记成守护。它们的唯一区别在于JVM 的退出条件:JVM 会检查系统里是否还有"用户线程"存活,只要有一个用户线程在跑,JVM 就不会退出;当所有用户线程都结束后,JVM 才会退出,此时守护线程会被强制终止,没有善后机会,也就是说守护线程里的 finally、关闭流这些"必须完成"的动作可能来不及执行。

守护线程的典型用途是"服务型的后台任务",比如 JVM 内部的 GC 线程、JIT 编译线程、Finalizer 线程、Reference Handler 线程,以及应用里的日志定期 flush、心跳上报这类任务——它们不需要保证执行完毕,服务完就行。

工程上的两个坑:第一,如果线程已经 start() 了再调用 setDaemon 会抛 IllegalThreadStateException,所以必须在 start 前设置;第二,守护线程创建的子线程默认继承守护属性,如果你希望子线程是用户线程,要显式 setDaemon(false)。

如果要让守护线程也能做收尾,可以用 Runtime.addShutdownHook 挂一个 hook,JVM 退出前会主动调 hook 里的代码,这就绕过了守护线程被强杀的坑。