Java守护线程的理解及应用

在Java中有两类线程,分别是User Thread(用户线程)和Daemon Thread(守护线程) 。
用户线程很好理解,我们日常开发中编写的业务逻辑代码,运行起来都是一个个用户线程。而守护线程相对来说则要特别理解一下。

1.1 什么是守护线程

在操作系统里面是没有所谓的守护线程的概念的,只有守护进程一说。但是Java语言机制是构建在JVM的基础之上的,这一机制意味着Java平台是把操作系统的底层给屏蔽了起来,所以它可以在它自己的虚拟的平台里面构造出对自己有利的机制。而Java语言或者说平台的设计者多多少少是收到Unix操作系统思想的影响,而守护线程机制又是对JVM这样的平台凑合,于是守护线程应运而生。

所谓的守护线程,指的是程序运行时在后台提供的一种通用服务的线程。比如垃圾回收线程就是一个很称职的守护者,并且这种线程并不属于程序中不可或缺的部分。因此,当所有的非守护线程结束时,程序也就终止了,同时会杀死进程中的所有守护线程。反过来说,只要任何非守护线程还在运行,程序就不会终止。

事实上,User Thread(用户线程)和Daemon Thread(守护线程)从本质上来说并没有什么区别,唯一的不同之处就在于虚拟机的离开:如果用户线程已经全部退出运行了,只剩下守护线程存在了,虚拟机也就退出了。 因为没有了被守护者,守护线程也就没有工作可做了,也就没有继续运行程序的必要了。

1.2 守护线程的使用与注意事项

守护线程并非只有虚拟机内部可以提供,用户也可以手动将一个用户线程设定/转换为守护线程。

在Thread类中提供了一个setDaemon(true)方法来将一个普通的线程(用户线程)设置为守护线程。

public final void setDaemon(boolean on);

在使用的过程中,有几点需要注意:
1.thread.setDaemon(true)必须在thread.start()之前设置,否则会抛出一个IllegalThreadStateException异常。这也就意味着不能把正在运行的常规线程设置为守护线程。 这点与操作系统中的守护进程有着明显的区别,守护进程是创建后,让进程摆脱原会话的控制+让进程摆脱原进程组的控制+让进程摆脱原控制终端的控制;所以说寄托于虚拟机的语言机制跟系统级语言有着本质上面的区别。

2.在Daemon线程中产生的新线程也是Daemon的。关于这一点又是与操作系统中的守护进程有着本质的区别:守护进程fork()出来的子进程不再是守护进程,尽管它把父进程的进程相关信息复制过去了,但是子进程的进程的父进程不是init进程,所谓的守护进程本质上说就是,当父进程挂掉,init就会收养该进程,然后文件0、1和2都是/dev/null,当前目录到/。

3.不是所有的应用都可以分配给Daemon线程来进行服务的,比如读写操作或者计算逻辑。因为这种应用可能在Daemon Thread还没来得及进行操作时,虚拟机已经退出了。这也就意味着,守护线程应该永远不去访问固有资源,如文件、数据库,因为它会在任何时候甚至在一个操作的中间发生中断。

下面以一个完成文件输出的守护线程任务作为例子:

import java.io.*;  class TestRunnable implements Runnable {public void run(){try {Thread.sleep(1000); // 守护线程阻塞1秒后运行  File f = new File("daemon.txt");FileOutputStream os = new FileOutputStream(f,true);os.write("daemon".getBytes());} catch(IOException e1) {  e1.printStackTrace();  } catch(InterruptedException e2) {  e2.printStackTrace();  }  }  
}  public class TestDemo2 {public static void main(String[] args) throws InterruptedException {Runnable tr = new TestRunnable();Thread thread = new Thread(tr);thread.setDaemon(true); // 设置守护线程(必须在thread.start()之前)thread.start(); // 开始执行分进程}
}

上面这段代码的运行结果是文件daemon.txt中没有daemon字符串。
但是如果把thread.setDaemon(true);这行代码注释掉,文件daemon.txt是可以被写入daemon字符串的,因为这个时候这个线程就是普通的用户线程了。
简单理解就是,JRE判断程序是否执行结束的标准是所有的前台线程(用户线程)执行完毕了,而不管后台线程(守护线程)的状态。

1.3 守护线程的应用场景

前面说了那么多,那么Daemon Thread的实际应用在那里呢?举个例子,Web服务器中的Servlet,在容器启动时,后台都会初始化一个服务线程,即调度线程,负责处理http请求,然后每个请求过来,调度线程就会从线程池中取出一个工作者线程来处理该请求,从而实现并发控制的目的。也就是说,一个实际应用在Java的线程池中的调度线程。

1.4 总结

从我的理解,守护线程就是用来告诉JVM,我的这个线程是一个低级别的线程,不需要等待它运行完才退出,让JVM喜欢什么时候退出就退出,不用管这个线程。
在日常的业务相关的CRUD开发中,其实并不会关注到守护线程这个概念,也几乎不会用上。
但是如果要往更高的地方走的话,这些深层次的概念还是要了解一下的,比如一些框架的底层实现。

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

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

相关文章

C#__资源访问冲突和死锁问题

/// 线程的资源访问冲突:多个线程同时申请一个资源,造成读写错乱。 /// 解决方案:上锁,lock{执行的程序段}:同一时刻,只允许一个线程访问该程序段。 /// 死锁问题: /// 程序中的锁过多&#xf…

vscode debug python launch.json添加args不起作用

问题 为了带入参数调试python 程序,按照网上搜到的教程配置了lauch.json文件,文件中添加了"args": [“model” “0” “path”] {// 使用 IntelliSense 了解相关属性。 // 悬停以查看现有属性的描述。// 欲了解更多信息,请访问: h…

深入浅出学Verilog--基础语法

1、简介 Verilog的语法和C语言非常类似,相对来说还是非常好学的。和C语言一样,Verilog语句也是由一连串的令牌(Token)组成。1个令牌必须由1个或1个以上的字符(character)组成,令牌可以是&#x…

某公司二面面试题总结

你们公司开发遵守怎么样的代码规范? 当编写Java代码时,遵守良好的代码规范对于代码的可读性和可维护性至关重要。以下是一些更详细的Java代码规范建议: 命名规范: 类名应该采用名词或名词短语,使用驼峰命名法&#xf…

弘玑RPA进阶攻略

弘玑RPA进阶攻略 01.弘玑RPA产品概要02.设计器的安装与卸载03.设计器特性与使用04.工程模式与发布05.变量06.字符串处理07.数组处理08.日期与时间09.数据表格10.对象处理11.逻辑组件12.界面自动化13.界面自动化抓取网页表格数据14.Excel使用15.执行器概览16.中控概览17.语法糖1…

Java常用配置项和命令行

JVM配置项说明 经典的参数搭配整理 -Xms4096M -Xmx4096M -Xmn2048M -XX:MetaspaceSize256M -XX:MaxMetaspaceSize256M -XX:UseParNewGC # 年轻代GC -XX:UseConcMarkSweepGC # 老年代GC -XX:CMSScavengeBeforeRemark # 标记钱先执行一次新生代GC,建议去掉 -XX…

day3_C++

day3_C 思维导图用C的类完成数据结构 栈的相关操作用C的类完成数据结构 循环队列的相关操作 思维导图 用C的类完成数据结构 栈的相关操作 stack.h #ifndef STACK_H #define STACK_H#include <iostream> #include <cstring>using namespace std;typedef int datat…

2023 年全国大学生数学建模竞赛题D 题 圈养湖羊的空间利用率思路详解+Python源码(二)

昨天已经将E题第一二问的详解和思路源码都写了出来&#xff0c;大家如果想从E题下手的话推荐参考本人文章&#xff0c;个人认为E题在建模上是优于D题的&#xff0c;毕竟有给出数据而且有明确的建模思路&#xff0c;E题我直接提供了Python源码直接可以运行即可&#xff1a; 202…

通过pyinstaller将python项目打包成exe执行文件

目录 第一步&#xff1a;安装pyinstaller 第二步&#xff1a;获取一个ico图标&#xff08;也即是自己这个exe文件最后的图标&#xff09; 第三步&#xff1a;打包 第一步&#xff1a;安装pyinstaller pip install pyinstaller 第二步&#xff1a;获取一个ico图标&#xff…

STC15单片机特有的PWM寄存器和普通定时器实现PWM输出

STC15单片机特有的PWM寄存器和普通定时器实现PWM输出 🌿主要针对STC15W4型号特有的6通道15位专门的高精度PWM。 ✨STC15W4K32S4系列单片机具有6通道15位专门的高精度PWM(带死区控制)和2通道CCP(利用它的高速脉冲输出功能可实现11~16位PWM);(STC15F/L2K60S2系列单片机具有3通…

Android逆向学习(番外一)smali2java部分文件无法反编译的bug与修复方法

Android逆向学习&#xff08;番外一&#xff09;smali2java部分文件无法反编译的bug与修复方法 一、前言 昨天我和往常一样准备着android逆向&#xff08;四&#xff09;的博客&#xff0c;结果发现smali2java对某些文件无法进行逆向&#xff0c;我不知道windows会不会产生这…

视频汇聚/视频云存储/视频监控管理平台EasyCVR安全检查的相关问题及解决方法2.0

开源EasyDarwin视频监控TSINGSEE青犀视频平台EasyCVR能在复杂的网络环境中&#xff0c;将分散的各类视频资源进行统一汇聚、整合、集中管理&#xff0c;在视频监控播放上&#xff0c;TSINGSEE青犀视频安防监控汇聚平台可支持1、4、9、16个画面窗口播放&#xff0c;可同时播放多…

windows10使用wheel安装tensorflow2.13.0/2.10.0 (保姆级教程)

安装过程 安装虚拟环境安装virtualenv安装满足要求的python版本使用virtualenv创建指定python版本的虚拟环境 安装tensorflow安装tensorflow-docs直接下载使用wheel下载 在VSCode编辑器中使用虚拟环境下的python解释器&#xff0c;并使用tensorflow常见错误 注意&#xff1a; t…

反序列化中_wakeup的绕过

文章目录 前言绕过方法变量引用属性个数不匹配(cve-2016-7124)C绕过fast-destruct其余GC回收机制 前言 反序列化中_wakeup扮演着非常重要的角色&#xff0c;ctf碰到很多的题目都有涉及到_wakeup绕过&#xff0c;写下这篇博客来总结下大部分绕过方法&#xff0c;其中会有例题具…

大数据导论 笔记

一、大数据方向 1、技术发展 计算机网络云计算大数据时代人工智能&#xff08;本科&#xff1a;使用&#xff0c;研究生&#xff1a;推导&#xff0c;博士&#xff1a;创新&#xff09; 2023年 大数据模型 人工智能元年 2、基础课程 hadoop 大数据基础 三大件&#xff1a;HDF…

java实现调用百度地图

这里使用的springbootthymeleaf实现&#xff0c;所以需要有springboot技术使用起来更方便 当然&#xff0c;只使用html加js也可以实现&#xff0c;下面直接开始 首先我们需要去百度地图注册一个AK&#xff08;百度地图开放平台 | 百度地图API SDK | 地图开发&#xff09; 找到左…

808协议是指中国国标GB/T 32960-2017《道路车辆运行数据远程监管与服务》通信协议,也被称为JT/T808协议

808协议是指中国国标GB/T 808协议是指中国国标GB/T 32960-2017《道路车辆运行数据远程监管与服务》通信协议&#xff0c;也被称为JT/T808协议。该协议规定了车辆与监管平台之间的通信规范&#xff0c;用于实现对道路车辆的远程监管和服务。 JT/T808协议主要包含以下几个方面的…

基于python+Django深度学习的音乐推荐方法研究系统设计与实现

摘 要 数字化时代带动着整个社会的信息化发展&#xff0c;随着数字媒体的不断发展&#xff0c;现在通多媒体数字产品的内容越来越丰富&#xff0c;传播影响力越来越强&#xff0c;以音乐为例&#xff0c;现在的音乐文化多样、音乐资源也异常的丰富&#xff0c;在这种大数据的环…

学会用命令行创建uni-app项目并用vscode开放项目

(创作不易&#xff0c;感谢有你&#xff0c;你的支持&#xff0c;就是我前行的最大动力&#xff0c;如果看完对你有帮助&#xff0c;请留下您的足迹&#xff09; 目录 创建 uni-app 项目 命令行创建 uni-app 项目 编译和运行 uni-app 项目&#xff1a; 用 VS Code 开发 uni…

Elasticsearch踩坑:启动时 报错 java.nio.file.NoSuchFileException \lib\dt.jar

原因&#xff1a; ES 8.0.x版本对应jdk17以上&#xff0c;jdk17等高版本的jdk在配置环境变量时无需配置 CLASSPATH 解决&#xff1a; 1.将 /etc/profile 中的CLASSPATH的环境变量删除 2.配置立即生效source /etc/profile 3.重启ES