来聊聊守护线程

写在文章前面

近期和朋友交流时谈及守护线程,遂整理一篇关于守护线程的文章,让读者会守护线程有更进一步的认识,本文整体内容如下:

在这里插入图片描述

你好,我叫sharkchili,目前还是在一线奋斗的Java开发,经历过很多有意思的项目,也写过很多有意思的文章,是CSDN Java领域的博客专家,也是Java Guide的维护者之一,非常欢迎你关注我的公众号:写代码的SharkChili,这里面会有笔者精心挑选的并发、JVM、MySQL数据库专栏,也有笔者日常分享的硬核技术小文。

在这里插入图片描述

关于守护线程的一些介绍

很多人对守护线程都不陌生,对于守护线程大部分读者都停留在JDK官方文档所介绍的概念:

The Java Virtual Machine exits when the only threads running are all daemon threads.

文档的意思是当JVM中不存在任何一个正在运行的非守护线程时,JVM进程会直接退出。

读起来很拗口对不对,没关系,本文就会基于几个代码示例,让你更深层次的理解守护线程。在此之前,读者不妨自测一下,下面这几道面试题:

  1. 守护线程和普通线程有什么区别?
  2. 守护线程默认优先级是多少?
  3. 若父线程为守护线程,在其内部创建一个普通线程,父线程停止,子线程是否也会停止呢?
  4. 如何创建守护线程池?
  5. 守护线程使用有哪些注意事项?

基于示例了解守护线程

守护线程和普通线程的区别

要了解区别就先来了解一下两者的使用,非守护线程,也就我们日常创建的普通线程,可以看到这段代码创建了一个普通线程,在无限循环的定时输出内容,而主线程仅仅是输出一段文字后就不做任何动作了。

public static void main(String[] args) {Thread t = new Thread(() -> {while (true) {log.info("普通线程执行了......");try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}}});t.start();log.info("主线程运行结束");}

对应的输出结果如下,可以看到,即使主线程停止运行了,而非守护线程也仍然会在运行,也就是JDK官方文档的字面含义,普通线程不停止,JVM就不停止运行:

12:44:57.022 [Thread-0] INFO com.sharkChili.webTemplate.Main - 普通线程执行了......
12:44:57.022 [main] INFO com.sharkChili.webTemplate.Main - 主线程运行结束
12:45:02.031 [Thread-0] INFO com.sharkChili.webTemplate.Main - 普通线程执行了......

基于上述代码,用setDaemon(true)将该线程设置为守护线程

public static void main(String[] args) {Thread t = new Thread(() -> {while (true) {log.info("守护线程执行了......");try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}}});//设置当前线程为守护线程t.setDaemon(true);t.start();log.info("主线程运行结束");}

输出结果如下,可以看到随着主线程的消亡,守护线程也会随之停止,不再运行,自此我相信读者可以理解JDK官方文档所说的那句话了,只要有一个普通线程在,JVM就不会退出,只要所有普通线程停止工作,JVM自动退出,守护线程也会自动结束。

12:44:23.239 [Thread-0] INFO com.sharkChili.webTemplate.Main - 守护线程执行了......
12:44:23.239 [main] INFO com.sharkChili.webTemplate.Main - 主线程运行结束

守护线程和普通线程优先级的区别

我们可以通过getPriority方法查看两者的区别:

public static void main(String[] args) {Thread t = new Thread(() -> {log.info("守护线程优先级:{}", Thread.currentThread().getPriority());});//设置当前线程为守护线程t.setDaemon(true);t.start();log.info("主线程运行结束,当前线程运行优先级:{}", Thread.currentThread().getPriority());}

从输出结果来看,两者的优先级是一样的,都为5:

12:54:36.344 [main] INFO com.sharkChili.webTemplate.Main - 主线程运行结束,当前线程运行优先级:5
12:54:36.344 [Thread-0] INFO com.sharkChili.webTemplate.Main - 守护线程优先级:5

父守护线程问题

我们创建了一个守护线程,在其runnable实现中创建一个子线程:

public static void main(String[] args) {Thread parentThread = new Thread(() -> {Thread childThread = new Thread(() -> {while (true) {log.info("子线程运行中,是否为守护线程:{}",Thread.currentThread().isDaemon());try {TimeUnit.HOURS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}}});childThread.start();log.info("parentThread守护线程运行中");});//设置当前线程为守护线程parentThread.setDaemon(true);parentThread.start();log.info("主线程运行结束");}

从输出结果来看,父线程为守护线程时,其内部创建的子线程也为守护线程,所以随着父线程的销毁,子线程也会同步销毁。

00:05:56.869 [Thread-1] INFO com.sharkChili.webTemplate.Main - 子线程运行中,是否为守护线程:true
00:05:56.869 [main] INFO com.sharkChili.webTemplate.Main - 主线程运行结束
00:05:56.869 [Thread-0] INFO com.sharkChili.webTemplate.Main - parentThread守护线程运行中

守护线程池的创建

public static void main(String[] args) {ExecutorService threadPool = Executors.newFixedThreadPool(10, ThreadFactoryBuilder.create().setNamePrefix("worker-").setDaemon(true).build());threadPool.execute(()->{while (true){try {log.info("守护线程运行了");Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}}});log.info("主线程退出");}

小结

守护线程的使用场景

因为守护线程拥有自动结束自己生命周期的特性,当JVM中没有一个普通线程运行时,JVM会退出,即所有守护线程会自动停止,所以守护线程的使用场景可以有以下几种:

  1. 垃圾回收线程就是典型的守护线程,在后台进行垃圾对象回收的工作。
  2. 非核心业务工作可交由守护线程,例如:各类信息统计、服务监控等,一旦进程结束运行则这些守护线程停止工作。

守护线程注意事项

  1. 复杂计算、资源回收这种不建议使用守护线程。
  2. setDaemon要在start方法前面,否者该设置会不生效。

我是sharkchiliCSDN Java 领域博客专家开源项目—JavaGuide contributor,我想写一些有意思的东西,希望对你有帮助,如果你想实时收到我写的硬核的文章也欢迎你关注我的公众号:
写代码的SharkChili,同时我的公众号也有我精心整理的并发编程JVMMySQL数据库个人专栏导航。

在这里插入图片描述

参考文章

Java 多线程之守护 (Daemon) 线程:https://blog.csdn.net/qq_33479841/article/details/121950775

JAVA多线程基础篇–守护线程(Daemon Thread):https://www.exception.site/java-concurrency/java-concurrency-daemon-thread

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/336085.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GCF:在线市场异质治疗效果估计的广义因果森林

英文题目:GCF: Generalized Causal Forest for Heterogeneous Treatment Effects Estimation in Online Marketplace 中文题目:GCF:在线市场异质治疗效果估计的广义因果森林 单位:滴滴&美团 时间:2022 论文链接…

关于TLS相关安全配置问题

近期被信安部门反馈了TLS几个安全漏洞。 SSL/TLS协议信息泄露漏洞(CVE-2016-2183)【原理扫描】SSL/TLS 受诫礼(BAR-MITZVAH)攻击漏洞(CVE-2015-2808)【原理扫描】SSL/TLS 服务器瞬时 Diffie-Hellman 公共密钥过弱【原理扫描】SSL/TLS RC4 信息泄露漏洞(CVE-2013-2566)【原理扫…

PINN物理信息网络 | 泊松方程的物理信息神经网络PINN解法

基本介绍 泊松方程是一种常见的偏微分方程,它在物理学和工程学中具有广泛的应用。它描述了在某个区域内的标量场的分布与该场在该区域边界上的值之间的关系。 物理信息神经网络(PINN)是一种结合了物理定律和神经网络的方法,用于…

2D和3D视觉技术有哪些不同特点?

​作为一个多年经验的机器视觉工程师,我将详细介绍2D和3D视觉技术的不同特点、应用场景以及它们能够解决的问题。在这个领域内,2D和3D视觉技术是实现自动化和智能制造的关键技术,它们在工业检测、机器人导航、质量控制等众多领域都有着广泛的…

无心剑中译塞缪尔·厄尔曼《青春》

Youth 青春 Samuel Ullman 塞缪尔厄尔曼 Youth is not a time of life; it is a state of mind; it is not a matter of rosy cheeks, red lips and supple knees; it is a matter of the will, a quality of the imagination, a vigor of the emotions; it is the freshness o…

Taro+vue3 实现电影切换列表

1.需求 我们在做类似于猫眼电影的小程序或者H5 的时候 我们会做到那种 左右滑动的电影列表,这种列表一般带有电影场次 2.效果 3.说明 这种效果在淘票票 猫眼电影上 都有的 ,一般电影类型的H5 或者小程序 这个是都有的 第一是好看 第二是客观性比较好 …

day7:消息队列与共享内存

思维导图: 消息队列原理: 进程在内核空间中维护出消息队列,每个进程借由消息队列的msgid对消息队列进行读写操作,消息队列中的信息是一个结构体,存储着消息的种类(身份证)和消息的内容&#xff…

《数据结构、算法与应用C++语言描述》-红黑树的C++实现-百万级数据量测试通过

红黑树 完整可编译运行代码见仓库:GitHub - Jasmine-up/Data-Structures-Algorithms-and-Applications/_3matrix。 如有问题请在评论区指出。另外,Github仓库会根据我的学习情况持续更新,欢迎大家点star,谢谢。 基本概念 红-黑…

智数融合|低代码入局,推动工业数字化转型走"深"向"实"

当下,“数字化、智能化”已经不再是新鲜词汇。事实上,早在几年前,就有企业开始大力推动数字化转型,并持续进行了一段时间。一些业内人士甚至认为,“如今的企业数字化已经走过了成熟期,进入了深水区。” 但事…

虚幻UE 材质-进阶边界混合之距离场限制PDO范围

基础边界混合那篇文章:虚幻UE 材质-边界混合之PDO像素深度偏移量 可以通过抖动来进行混合,但是有问题的点在与抖动发生的位置只需要在两物体的交界处 所以本篇文章会通过距离场限制来限制抖动的位置,防止其他地方发生抖动影响画面。 文章目录…

三、yolov8训练结果查看和模型预测

训练结果查看 1、在模型训练结束后,如下图所示,找到该文件夹。 2、然后找到weights文件夹中的best.pt文件,这就是该数据训练后的模型。 模型预测 1、在assets文件夹下创建FPC-2文件夹,放入一些同类FPC预测结果。 2、和训练…

HarmonyOS@Link装饰器:父子双向同步

Link装饰器:父子双向同步 子组件中被Link装饰的变量与其父组件中对应的数据源建立双向数据绑定。 说明 从API version 9开始,该装饰器支持在ArkTS卡片中使用。 概述 Link装饰的变量与其父组件中的数据源共享相同的值。 装饰器使用规则说明 Link变…