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

共 1833字,需浏览 4分钟

 ·

2023-08-19 22:34

守护线程使用示例

看下面这段代码: f4d3a0ebfa85ee6764de14d941fc34d8.webp在上面的示例中,我们创建了一个守护线程daemonThread,并将其设置为守护线程。主线程休眠一段时间后,主线程结束,程序退出,此时守护线程也会随之结束。守护线程的DaemonTask会不断地输出消息,模拟后台任务的执行。当主线程结束后,你会注意到守护线程DaemonTask不再输出消息,因为它被 JVM 中止了。

什么是守护线程

Java 把线程分成两类:用户线程(User Thread) + 守护线程(Daemon Thread)守护线程的使用有以下要点:
  • 当程序中所有的用户线程执行完毕之后,不管守护线程是否结束,系统都会自动退出(也就是说只要存在一个用户线程在允许,守护线程就不会结束)
  • 守护线程必须在start启动前通过setDaemon()方法将状态设置为 true,启动后就不能进行设置,否则报 InterruptedException 异常
  • 守护线程存在被 JVM 强制终止的风险,所以在守护线程中尽量不去访问系统资源,例如打开文件等,因为虚拟机退出时,守护线程没有任何机会来关闭文件,这会导致数据丢失,所以守护线程适合执行无需完整执行的后台任务
  • 守护线程中创建的线程也是守护线程
JVM 进程中的 GC 线程就是一个守护线程,这样设计目的很明确,当你所有的程序都执行完毕了,留着这个 GC 线程就没有任何意义了。反过来可以设想,如果把 GC 线程设计成非守护线程,当你明确你的程序都执行完毕了,但是就是不自动退出岂不是很奇怪?

守护线程的底层原理

守护线程底层原理是啥?为什么用户线程结束守护线程就能自动退出?(相信很多很多小伙伴遇到这个题都会直接懵,属于低频但重点的考点)我们看下 JVM 源码thread.cpp文件,这里是实现线程的代码。可以盲猜有一段代码监测着当前非守护线程的数量,不然怎么知道现在只剩下守护线程呢?很有可能是在移除线程的方法里面,跟着这个思路,我们看看该文件的remove()方法。代码如下 6d0d657f3a3770a97a4d9855f66f5989.webp我在里面加了一些注释,可以发现,果然是我们想的那样,里面有_number_of_non_daemon_threads记录着非守护线程的数量,而且当非守护线程数为 1 时,就会唤醒在destory_vm()方法里面等待的线程,紧接着我们看看destory_vm()代码,同样是在thread.cpp文件下: b203a665cccc1a1865a54c9ffb56996a.webp可以看到当非守护线程数量大于 1 时,就一直等待,直到剩下一个非守护线程时,就会在线程执行完后,退出 JVM。这时候又有一个点需要搞清楚,就是什么时候调用的destroy_vm()方法呢?还是通过查看代码以及注释,发现是在main()方法执行完成后触发的。在java.c文件的JavaMain()方法里面,最后执行完调用了LEAVE()方法,该方法调用了(*vm)->DestroyJavaVM(vm);来触发 JVM 退出,最终调用destroy_vm()方法。 bc1b3cfb31ed20de146fcb781362abaf.webp总结下就是: Java 程序在 main 线程执行退出时,会触发执行 JVM 退出操作(destroy_vm()方法),但是该方法会等待所有非守护线程(用户线程)都执行完,具体原理是使用变量_number_of_non_daemon_threads统计非守护线程的数量,这个变量在新增线程和删除线程时会做增减操作。另外衍生一点就是:当 JVM 退出时,所有还存在的守护线程会被抛弃,既不会执行 finally 部分代码,也不会 catch 异常。这个很明显,JVM 都退出了,守护线程还能独自存在?
    
      

    963b4da4f7d0cf8c74f97868607aa5e7.webp

          
            

              

1、老黄赢麻了!英伟达H100订单排到24年,马斯克都坐不住了

2、明明是工作经验越久越吃香,为什么程序员却不是?

3、中国的独立开发者都在开发些什么?

4、来了!谷歌代码编辑器,代码效率翻倍,真香…

5、Linus 亲自 review 代码,希望平息关于 Bcachefs 文件系统的 “内斗”

9eb023d35b9019c4ea977a14a715689b.webp

1f563cef21402b7dffe2a393e431c2a1.webp

2a78ae09e11b6e333d8451a649c4234e.webp

1bbc76e25158340bc33b263575ad7591.webp

点在看

浏览 39
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报