李林超博客
首页
归档
留言
友链
动态
关于
归档
留言
友链
动态
关于
首页
Java
正文
07.并发编程之守护线程
Leefs
2022-10-09 PM
985℃
0条
[TOC] ### 一、概述 Java提供了两种线程,**守护线程**和**用户线程**。 + **用户线程**:平常使用时所创建的普通线程,也叫非守护线程。 + **守护线程(即 Daemon thread)**:一般是为工作线程服务的线程,当所有的用户线程结束,守护线程自动结束。 ### 二、作用 + **JVM 中的垃圾回收线程就是典型的守护线程**,当进程中没有非守护线程了,则垃圾回收线程也就没有存在的必要了,自动销毁。 > 垃圾回收是一个一直需要运行的机制,但是当没有用户线程的时候,也就不需要垃圾回收线程了,守护线程刚好满足这样的需求。 + Tomcat 中的 Acceptor 和 Poller 线程都是守护线程,所以 Tomcat 接收到 shutdown 命令后,不会等待它们处理完当前请求 + 守护线程经常会执行一些后台任务,因此有时它也被称为后台线程,当希望关闭某个线程的时候,或者退出 JVM 进程的时候,一些线程能够自动关闭,此时就可以考虑用守护线程来完成这样的工作。 ### 三、使用 #### 3.1 Java守护程序线程的方法 `java.lang.Thread`类为java守护程序线程提供了两种方法。 | 方法 | 描述 | | --------------------------------------- | ------------------------------------------------------------ | | `public void setDaemon(boolean status)` | 用于将当前线程标记为守护程序线程或用户线程(true:守护线程,false:用户线程)。 | | `public boolean isDaemon()` | 用于检查当前线程是否是守护线程。 | #### 3.2 示例 ```java @Slf4j(topic = "c.Test14") public class Test14 { public static void main(String[] args) { log.debug("start..."); Thread t1 = new Thread(() -> { while (true) { log.debug("t1 running..."); Sleeper.sleep(1); } },"t1"); // 将 t1 设置为守护线程 t1.setDaemon(true); // 启动线程 t1.start(); Sleeper.sleep(3); log.debug("end..."); } } ``` **运行结果** ``` 10:34:59.209 c.Test14 [main] - start... 10:34:59.236 c.Test14 [t1] - t1 running... 10:35:00.251 c.Test14 [t1] - t1 running... 10:35:01.263 c.Test14 [t1] - t1 running... 10:35:02.243 c.Test14 [main] - end... ``` 如果注释掉`t1.setDaemon(true);`代码运行结果 ``` 10:39:37.827 c.Test14 [main] - start... 10:39:37.856 c.Test14 [t1] - t1 running... 10:39:38.872 c.Test14 [t1] - t1 running... 10:39:39.880 c.Test14 [t1] - t1 running... 10:39:40.872 c.Test14 [main] - end... 10:39:40.887 c.Test14 [t1] - t1 running... 10:39:41.888 c.Test14 [t1] - t1 running... 10:39:42.895 c.Test14 [t1] - t1 running... 10:39:43.904 c.Test14 [t1] - t1 running... ...... ``` **说明** 上面代码存在两个线程,一个是由 JVM 启动的 main 线程,另外一个是创建的 thread: + 如果将 `thread.setDaemon(true); `注释掉,JVM 永远也不会退出,原因是 JVM 进程还存在一个非守护线程 thread; + 如果 `thread.setDaemon(true);` 不注释掉,也就是说通过 `setDaemon` 方法将 thread 设置为守护线程,那么当 main 进程结束了生命周期, JVM 也会随之退出运行,当然 thread 线程也会结束。 ### 四、注意事项 1. **守护线程一般具有较低的优先级**,将一个线程设置为守护线程的方法就是在调用start()启动线程之前调用对象的`setDaemon(true)`方法,若将以上参数设置为false,则表示的是用户进程模式。 2. 在一个守护线程中产生了其他的线程,那么这些新产生的线程默认还是守护线程,用户线程也是如此。 3. `setDaemon(true)`必须在调用start()启动线程之前,否则会抛出`IllegalThreadStateException`异常,该线程默认为用户线程,继续执行。 4. 守护线程不应该操作文件、数据库等资源,避免主线程关闭而未能关闭守护线程的资源,并且它会在任何时候甚至在一个操作的中间发生中断。
标签:
并发编程
非特殊说明,本博所有文章均为博主原创。
如若转载,请注明出处:
https://lilinchao.com/archives/2464.html
上一篇
06.并发编程之interrupt方法详解
下一篇
08.并发编程之线程状态
评论已关闭
栏目分类
随笔
2
Java
326
大数据
229
工具
31
其它
25
GO
47
NLP
4
标签云
Elasticsearch
MyBatis-Plus
JavaScript
GET和POST
Azkaban
机器学习
字符串
Java编程思想
Quartz
Spark Streaming
稀疏数组
RSA加解密
DataWarehouse
数学
设计模式
JavaSE
Yarn
VUE
递归
序列化和反序列化
Spark
SpringCloudAlibaba
FileBeat
Hadoop
nginx
MyBatisX
持有对象
并发线程
JavaWeb
SpringBoot
友情链接
申请
范明明
庄严博客
Mx
陶小桃Blog
虫洞
评论已关闭