我麻了,京东一面:守护线程如何实现的?

守护线程的实现主要依赖于不同的线程类型和JVM生命周期管理机制。
它的基本逻辑是通过计算非守护线程的数量来判断JVM是否正在终止。
下面是具体的实现原理和要点: 守护线程的关键特性。
线程类型的分离:Java将线程分为用户线程(UserThread)和守护线程(DaemonThread)。
使用 setDaemon(true) 将线程标记为守护线程(必须在 start() 之前设置)。
JVM退出条件:当所有用户线程执行完毕(数量归零)时,JVM将强制终止所有守护线程,无论它们是否仍在运行。
对资源访问的限制。
守护线程应避免访问持久性资源(例如文件和数据库),因为它们可能会突然终止,从而导致资源未释放或数据不一致。
示例中的主线程终止后,DaemonTask 线程会被 JVM 强制终止并停止打印消息。
底层 JVM 实现使用以下机制管理守护线程的生命周期: 非守护线程计数器。
在JVM源代码(thread.cpp)中,_number_of_non_daemon_threads变量用于动态计算存活的用户线程的数量。
当添加或删除线程时,计数器将同步递增或递减(例如,在Remove()方法中更新)。
JVM退出进程触发条件:main()方法完成后,调用LEAVE()→DestroyJavaVM()→destroy_vm()。
等待机制:Destroy_vm() 将阻塞,直到 _number_of_non_daemon_threads 为零(即所有用户线程都结束)。
强制终止:计数器达到零后,JVM 终止并终止所有守护线程(不执行异常或终止处理)。
线程继承:守护线程创建的子线程默认继承守护线程的属性(无需显式设置)。
例如:GC线程作为守护线程,之后不需要手动终止完成该计划。
关键代码的路径。
离开主线程运行java.c→JavaMain()→LEAVE()→DestroyJavaVM()→destroy_vm()。
管理计数器 新线程:Threads::create_vm() 初始化一个计数器。
删除线程:Thread::remove() 会递减计数器,如果计数器达到零,则运行 Destroy_vm()。
设计含义: 资源优化:避免程序终止后剩余无用的线程(例如GC线程)。
风险隔离:强制终止守护线程以防止资源泄漏,但开发人员应谨慎使用(例如避免在守护线程上持有锁或文件句柄)。
示例场景 适用场景:后台日志、心跳检测、监控任务等非关键操作。
不适用场景:文件写入、数据库事务等需要完全执行的逻辑(可能因JVM退出导致数据损坏)。
说明:守护线程的实现是基于JVM动态监控用户线程数量,退出时间由_number_of_non_daemon_threads计数器决定。
其设计的本质是平衡资源释放和程序可靠性。
它适用于实用任务,但应避免关键资源操作。
了解这一机制有助于您在多线程编程中合理选择线程类型,避免潜在的风险。

java中守护线程与非守护线程的区别

守护线程称为精灵线程。
当程序中只剩下守护线程时,程序就会退出。
守护线程的作用类似于作为 JVM 垃圾收集机制在后台静默执行。
这是一个守护线程。
非守护线程不会。