详解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自定义环形对比图的具体代码,供大家参考,具体内容如下1.首先在res/values里创建一个attr.xm
- 概述什么是动态编程?动态编程解决什么问题?Java中如何使用?什么原理?如何改进?(需要我们一起探索,由于自己也是比较菜,一般深入不到这个程
- 前言Java8 由Oracle在2014年发布,是继Java5之后最具革命性的版本。Java8吸收其他语言的精髓带来了函数式编程,lambd
- 本文实例讲述了Java实现SSL双向认证的方法。分享给大家供大家参考,具体如下:我们常见的SSL验证较多的只是验证我们的服务器是否是真实正确
- ContentProvider是内容提供者,可以跨进程提供数据。大家都知道,ContentProvider的启动,是在Application
- spring容器是负责实例化、配置、组装组件的容器。容器的配置有很多,常用的是xml、Java注解和Java代码。在spring中Ioc容器
- springboot+调用支付宝第三方接口(沙箱环境)大神勿喷!!网址:https://developers.alipay.com/plat
- 前言使用Java8的新特性Stream流式处理,可以提高对于集合的一些操作效率,再配合lambda表达式,可以极致的简化代码,尤其还有并行流
- 很多童鞋反应在吧项目导入到eclipse(myeclipse)时中文会有乱码,修改了编码格式后还是乱码,这里给大家介绍一下关于中文乱码时修改
- 因为mybatis好使,所以几乎需要操作数据库的时候,我都会使用mybatis,而且在一个正式的项目中,同时存在BS和CS的程序,都使用的M
- 什么是volatile关键字volatile是Java中用于修饰变量的关键字,其可以保证该变量的可见性以及顺序性,但是无法保证原子性。更准确
- 在项目迁移到Spring Boot之后,发生内存使用量过高的问题。本文介绍了整个排查过程以及使用到的工具,也非常适用于其他堆外内存排查。背景
- 加载本地图片在项目目录下创建assets文件夹,再在其文件夹下创建images文件夹,后面将需要的图片复制到其中即可在pubspec.yam
- jar包运行时提示jar中没有主清单属性解决办法在pom文件中添加<build> &n
- 前言项目使用redis作为缓存数据,但面临着问题,比如,项目A,项目B都用到redis,而且用的redis都是一套集群,这样会带来一些问题。
- 6.0的手机对于写入手机需要申请权限的我做了如下处理下面我贴出代码package com.example.admin.sdapplicati
- 每当想找哪个运算符优先级高时,很多时候总是想找的就没有,真让人气愤!现在,终于有个我个人觉得非常全的,分享给大家,欢迎拍砖!C语言运算符优先
- 登陆是系统最基础的功能之一。这么长时间了,一直在写业务,这个基础功能反而没怎么好好研究,都忘差不多了。今天没事儿就来撸一下。以目前在接触和学
- 话不多说,请看实例代码String ip = request.getHeader("x-forwarded-for");
- 本文实例讲述了Java Web项目部署在Tomcat运行出错与解决方法。分享给大家供大家参考,具体如下:1、在部署Java Web项目的过程