题目:什么是守护线程,和普通线程有什么区别?
难度:low
标签:java/thread, difficulty/low
评分:⭐☆☆☆☆(1/5)
守护线程指的是更隐性的一个低优先级线程,它会在其他线程结束之后做恢复使用,恢复保护其他线程。我印象中在 Docker 中有类似的东西,守护线程,然后 ZAM 中也有。
守护线程执行的时候需要在 Java 中守护线程执行的时候需要做设置,把当前线程设置为,把一个线程设置为守护线程。守护线程的区别,我没什么印象了。
优点:
setDaemon(true) 的存在感有)不足:
补充:
ThreadLocal 的 Reference Handler、日志 flush 线程main 本身就是用户线程,如果只有守护线程跑完 main 也返回了,JVM 直接退出,守护线程来不及执行"善后"setDaemon(true) 后立刻启动;如果线程已 start 再调 setDaemon 会抛 IllegalThreadStateException核心考点定位:区分 Java 中"用户线程"和"守护线程"的生命周期语义,考察对 JVM 退出条件的理解。
知识点拆解:
Thread 有一个 daemon 标志位(setDaemon(true) 设置),JVM 退出判断时只看用户线程数,守护线程不参与计数考察方向:
Thread.shouldYield() / java.lang.ApplicationShutdownHooks)Thread.setPriority / Thread.setAffinityNanos)延伸递进面试题:
Runtime.addShutdownHook 注册 hook;或改用用户线程 + CountDownLatch面试官您好,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 里的代码,这就绕过了守护线程被强杀的坑。