详解Java线程-守护线程与用户线程
作者:情深见鹿 发布时间:2023-11-25 00:17:29
干java 开发这么多年, 之前一直没留意java 进程还区分守护进程和用户进程。守护进程这个概念最早还是在linux系统中接触的,直到近期使用java开发心跳检测功能时,使用Timer时才发现原来java也有守护线程的概念。
1. Java 线程
1.1 守护线程与用户线程
Java 线程分为守护线程(DaemonThread) 和 用户线程(UserThread)两类.
通常情况下,我们使用Thread 创建的线程在默认情况下都属于用户线程, 当在启动线程之前, 执行thread.setDaemon(true)时, 线程会变成守护线程。
其实在本质上,用户线程和守护线程并没有太大区别,唯一的区别就是会影响虚拟机的退出(程序的终止)。当jvm中只剩下守护线程时,虚拟机会退出,及程序终止;而当jvm中至少拥有一个用户线程时,jvm都不会退出。
1.2 守护线程特点
Java 中的守护线程和linux 中的守护进程还是有些区别的, linux 守护进程时系统级别的, 当系统退出时, 才会终止. 而java 中的守护线程时jvm 级别的, 当jvm中无任何用户进程时, 守护进程销毁, jvm 退出, 程序终止. 笔者认为java 守护进程的最主要的特点有:
守护进程是运行在程序后台的线程
守护进程创建的进程,依然时守护进程
守护进程不会影响jvm的退出,当jvm只剩余守护进程时,jvm 进行退出
守护进行在jvm退出时,自动销毁
在开发java 守护线程时, 需要注意:
在线程启动之前, 及执行thread.start() 方法前, 设置thread.setDemon(true);
在守护线程中启动的子线程也是守护线程
守护线程不建议进行写操作, 因为守护进程随时可能结束。
1.3 守护线程适用场景
针对于守护线程的特点,笔者认为,java 守护线程通常可用于开发一些为其它用户线程服务的功能。比如说心跳检测,事件监听等。Java 中最有名的守护进程当属GC(垃圾回收)
2. java 守护线程开发
开发守护进程时需要注意两点:
必须在线程启动之前,即执行thread.start()方法前, 执行thread.setDaemon(true) 方法,否则会抛出异常IllegalThreadStateException
守护线程中创建的线程也是守护线程
2.1 测试程序退出
注释thread.setDaemon(true)时, 线程为用户线程, 程序进行无线循环, 程序不终止。
设置thread.setDaemon(true)后, 线程变成守护线程, 程序直接终止, 仅输出一行信息"main thread done"。 因为程序执行完system 语句之后, main 程序作为唯一的一个用户线程执行结束了, jvm 中只剩下一个守护进程,所以jvm 便退出了。
public class TestThread {
public static void main(String[] args) {
AnsyTask ansyTask = new AnsyTask();
Thread thread = new Thread(ansyTask);
// 设置线程为异步线程
// thread.setDaemon(true);
// 启动线程
thread.start();
System.out.println("main thread done");
}
}
class AnsyTask implements Runnable{
@Override
public void run() {
while (true){
System.out.println(LocalDateTime.now() + "-hello,thread");
}
}
}
2.2 测试守护线程中创建新的线程
测试会发现, 默认情况下, 守护线程创建的子线程依然是守护线程,用户创建的守护线程依然时用户线程。也可以在创建子线程时通过setDaemon()方法修改.
public class TestThread {
public static void main(String[] args) throws InterruptedException {
AnsyTask ansyTask = new AnsyTask();
Thread thread = new Thread(ansyTask);
// 设置线程为异步线程
thread.setDaemon(true);
// 启动线程
thread.start();
// 给守护线程点儿执行时间
Thread.sleep(1000l);
}
}
class AnsyTask implements Runnable{
@Override
public void run() {
Thread thread = new Thread("subThread");
System.out.println(thread.getName() + " is daemon:" + thread.isDaemon());
}
}
以上所述是小编给大家介绍的Java守护线程与用户线程详解整合,希望对大家有所帮助。
来源:https://blog.csdn.net/zongf0504/article/details/88924995


猜你喜欢
- Android的消息机制几乎是面试必问的话题,当然也并不是因为面试,而去学习,更重要的是它在Android的开发中是必不可少的,占着举足轻重
- 本文介绍的是关于Mybatis中用OGNL表达式处理动态sql的相关内容,分享出来供大家参考学习,下面来一起看看详细的介绍:常用的Mybat
- 代码实例:<%@ page language="java" contentType="text/html
- 首先使用PImage来实例化对象,再通过loadImage赋值,两层for循环遍历图片上的像素点,每隔5个像素点,画一个直径为3的圆。颜色通
- 本文实例讲述了Spring和Hibernate的整合操作。分享给大家供大家参考,具体如下:一 web配置<?xml version=&
- C#中using指令的用法1.using指令using + 命名空间名字,这样可以在程序中直接用命令空间中的类型,而不必指定类型的详细命名空
- 对于Android 的手势不光在软件中会经常用到,比如浏览器中的翻
- 进度条样式在项目中经常可以见到,下面小编给大家分享Android三种方式实现ProgressBar自定义圆形进度条。Android进度条有4
- sum(参数) 列名作为参数项目中有很多个字段,当字段为空的时候,求该列的平均值并赋值给该字段。如: id
- 下面是一个邮件接收的工具类,有点长!!!public class ReciveMail { private MimeMessage msg
- 一、网络爬虫的基本知识网络爬虫通过遍历互联网络,把网络中的相关网页全部抓取过来,这体现了爬的概念。爬虫如何遍历网络呢,互联网可以看做是一张大
- 本文实例讲述了Android实现Activity、Service与Broadcaster三大组件之间互相调用的方法。分享给大家供大家参考,具
- 其中包含两个jsp文件,分别为login.jsp和index.jsp代码如下:login.jsp<%@ page language=&
- 前言本文主要给大家介绍了关于java poi导入Excel通用工具类的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍
- ThreadLocal类,代表一个线程局部变量,通过把数据放在ThreadLocal中,可以让每个线程创建一个该变量的副本。也可以看成是线程
- 一:在springboot中使用事物遇到的坑1.我们知道spring中的事物分为两种:一种是编程式事物,一种是声明式事物。顾名思义,编程式事
- 本文实例为大家分享了Android实现闪屏页效果的具体代码,供大家参考,具体内容如下1.效果图2.闪屏页逻辑及布局2.1 activity_
- 学习C#编程最常见的示例程序是在控制台应用程序中输出Hello World!using System;namespace DemoMainA
- 可能开发安卓的人大多数都用过很多下拉刷新的开源组件,但是今天用了官方v4支持包的SwipeRefreshLayout觉得效果也蛮不错的,特拿
- Spring Boot如何实现分布式系统中的服务发现和注册?随着互联网的快速发展,越来越多的企业开始将自己的业务迁移到分布式系统中。在这种情