java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java守护线程Daemon

Java守护线程Daemon原理+实战完全解析(彻底搞懂后台线程设计)

作者:暗暗别做白日梦

Daemon线程是一种支持性线程,因为它主要用作程序中台调度以及支持性工作,这篇文章主要介绍了Java守护线程Daemon原理及实战完全解析的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下

一、先讲单词:Daemon 到底是什么意思?

1. 发音与拼写

Daemon /ˈdiːmən/(和 Demon 读音一样,但含义完全不同

2. 原始含义(古希腊语)

3. 核心翻译

Daemon = 守护神 / 后台守护者

二、为什么 Java 里叫「守护线程」?

1. 技术传承(Unix 系统起源)

Daemon 最早是 Unix/Linux 系统的术语:

Java 语言直接沿用了这个概念:

2. 功能完全匹配「守护」二字

这个线程的行为,和 「守护神」一模一样:

  1. 默默干活:在后台运行,不干扰主线程(用户线程)
  2. 依附主人:主线程(业务线程)活着,它就干活
  3. 主人退场,它立刻消失:主线程关闭,它不拖累程序
  4. 只做辅助:为核心业务提供支持,不抢主角

三、结合代码,一秒理解

订单超时监听线程:

thread.setDaemon(true); 

这个线程就是订单服务的守护神

完美对应 Daemon(守护神)的含义!

四、极简总结(终身不忘)

  1. Daemon 本意守护神、后台守护者(不是恶魔!)
  2. 技术起源:Unix 后台服务叫守护进程,Java 沿用
  3. 为什么叫守护线程:它在后台默默守护主线程,主人在它在,主人走它走,纯辅助、不添乱

如果不加thread.setDaemon(true),默认创建的是:用户线程

一、什么是守护线程?

Java 中的线程分为两大类,地位完全不同:

  1. 用户线程(User Thread)也叫非守护线程,是程序的核心工作线程。比如:Spring 主线程、HTTP 请求处理线程、我们编写的业务逻辑线程。    ✅ JVM(Java 虚拟机)会等待所有用户线程执行完毕,才会退出。

  2. 守护线程(Daemon Thread)也叫后台服务线程,是为用户线程提供辅助服务的线程。比如:GC 垃圾回收线程、我们的订单超时监听线程。❌ JVM 不会等待守护线程,当所有用户线程结束时,守护线程会被强制立即终止

一句话总结

用户线程是主人,守护线程是仆人;主人下班(程序关闭),仆人立刻下岗,绝不拖延!

二、核心特性

守护线程有两个不可违背的特性,是设计的核心:

  1. 依附性:守护线程的生命周期完全依赖用户线程,用户线程全部退出,守护线程自动销毁;
  2. 低优先级:默认优先级较低,仅在后台默默提供辅助服务,不影响核心业务。

三、实战场景:订单超时消费者为什么用守护线程?

回到业务代码:订单支付超时监听线程这个线程需要24 小时死循环监听 Redis 阻塞队列,处理超时订单。

@PostConstruct
public void start() {
    executorService = Executors.newSingleThreadExecutor(r -> {
        // 创建后台监听线程
        Thread thread = new Thread(r, "order-payment-timeout-consumer");
        // 核心:设置为守护线程
        thread.setDaemon(true);  
        return thread;
    });
    // 启动循环监听
    executorService.submit(this::consumeLoop);
}

为什么要给这个线程设置setDaemon(true)?

我们的监听线程是纯后台辅助线程,它的唯一作用是服务订单业务:

四、不设置守护线程的严重后果

如果删掉 thread.setDaemon(true),会发生生产级 BUG

  1. 你停止 Spring 服务(执行关闭命令);
  2. 所有用户线程都已退出;
  3. 但你的订单监听线程是用户线程,还在死循环运行;
  4. JVM 会一直等待这个线程结束,无法正常退出
  5. 最终导致:服务器进程残留、端口占用、服务无法重启

通俗比喻

五、守护线程使用注意事项

守护线程不能用来执行重要的、不可中断的业务,因为它会被 JVM 强制杀死,没有任何收尾机会。

禁忌场景

  1. ❌ 不要在守护线程中做:数据库事务提交、文件写入、数据持久化;
  2. ❌ 不要在守护线程中做:需要保证执行完成的核心逻辑;

适用场景

  1. ✅ 后台监听、定时扫描(如我们的订单超时监听);
  2. ✅ 日志收集、监控上报;
  3. ✅ JVM 垃圾回收(GC);
  4. ✅ 心跳检测、后台清理。

我们的订单超时线程:只是从 Redis 取任务、执行业务,被强制终止也不会造成数据问题,完美适配守护线程。

六、关键知识点补充

  1. 守护线程的继承性如果一个线程是守护线程,它创建的子线程默认也是守护线程;用户线程创建的子线程,默认是用户线程。

  2. 设置时机setDaemon(true) 必须在线程启动前设置,线程运行后设置会直接报错!

七、总结

核心结论

  1. Daemon = 守护线程,是为用户线程服务的后台辅助线程;
  2. 主人(用户线程)退出,仆人(守护线程)强制终止
  3. 我们的订单超时监听线程设置为守护线程,是为了服务关闭时线程自动销毁,避免 JVM 无法退出
  4. 这是 Java 后台线程设计的标准最佳实践

一句话记忆

守护线程,随程序生,随程序死;不拖后腿,不占资源,后台服务的最佳选择!

适用场景:分布式定时任务、延迟队列监听、后台扫描、辅助服务线程核心作用:保证服务优雅启停,避免进程残留

到此这篇关于Java守护线程Daemon原理+实战完全解析的文章就介绍到这了,更多相关Java守护线程Daemon内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文