详解Java线程-守护线程与用户线程

作者:情深见鹿 时间:2023-11-25 00:17:29 

干java 开发这么多年, 之前一直没留意java 进程还区分守护进程和用户进程。守护进程这个概念最早还是在linux系统中接触的,直到近期使用java开发心跳检测功能时,使用Timer时才发现原来java也有守护线程的概念。

1. Java 线程

1.1 守护线程与用户线程

Java 线程分为守护线程(DaemonThread) 和 用户线程(UserThread)两类.

  1. 通常情况下,我们使用Thread 创建的线程在默认情况下都属于用户线程, 当在启动线程之前, 执行thread.setDaemon(true)时, 线程会变成守护线程。

  2. 其实在本质上,用户线程和守护线程并没有太大区别,唯一的区别就是会影响虚拟机的退出(程序的终止)。当jvm中只剩下守护线程时,虚拟机会退出,及程序终止;而当jvm中至少拥有一个用户线程时,jvm都不会退出。

1.2 守护线程特点

Java 中的守护线程和linux 中的守护进程还是有些区别的, linux 守护进程时系统级别的, 当系统退出时, 才会终止. 而java 中的守护线程时jvm 级别的, 当jvm中无任何用户进程时, 守护进程销毁, jvm 退出, 程序终止. 笔者认为java 守护进程的最主要的特点有:

  1. 守护进程是运行在程序后台的线程

  2. 守护进程创建的进程,依然时守护进程

  3. 守护进程不会影响jvm的退出,当jvm只剩余守护进程时,jvm 进行退出

  4. 守护进行在jvm退出时,自动销毁

在开发java 守护线程时, 需要注意:

  1. 在线程启动之前, 及执行thread.start() 方法前, 设置thread.setDemon(true);

  2. 在守护线程中启动的子线程也是守护线程

  3. 守护线程不建议进行写操作, 因为守护进程随时可能结束。

1.3 守护线程适用场景

针对于守护线程的特点,笔者认为,java 守护线程通常可用于开发一些为其它用户线程服务的功能。比如说心跳检测,事件监听等。Java 中最有名的守护进程当属GC(垃圾回收)

2. java 守护线程开发

开发守护进程时需要注意两点:

  1. 必须在线程启动之前,即执行thread.start()方法前, 执行thread.setDaemon(true) 方法,否则会抛出异常IllegalThreadStateException

  2. 守护线程中创建的线程也是守护线程

2.1 测试程序退出

  1. 注释thread.setDaemon(true)时, 线程为用户线程, 程序进行无线循环, 程序不终止。

  2. 设置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

标签:Java,守护线程,用户线程
0
投稿

猜你喜欢

  • Flutter有无状态类与State及生命周期详细介绍

    2022-12-27 15:48:53
  • 如何安装java的运行环境IDEA

    2022-09-20 10:42:38
  • Java通过HttpClient进行HTTP请求的代码详解

    2022-06-04 09:50:20
  • C# WinForm中Panel实现用鼠标操作滚动条的实例方法

    2021-08-08 01:52:42
  • 全面分析Java文件上传

    2021-12-09 13:22:52
  • EditText限制小数点前后位数的实例

    2023-04-10 03:56:14
  • 使用Java编写一个简单的Web的监控系统

    2023-02-18 04:00:19
  • C++实现企业职工工资管理系统

    2023-11-02 17:34:34
  • 浅谈java 面对对象(抽象 继承 接口 多态)

    2022-04-01 07:23:50
  • Java的可变参数与Collections类的功能示例解析

    2022-03-05 18:45:47
  • Android底部菜单简单应用

    2022-03-25 18:09:58
  • java数组元素的引用实例讲解

    2023-12-02 16:40:32
  • Android从服务器获取图片的实例方法

    2022-08-27 04:03:46
  • Android毕业设计记事本APP

    2023-04-22 20:55:21
  • IDEA使用GsonFormat完成JSON和JavaBean之间的转换

    2021-06-10 11:30:30
  • Android 自定义布局竖向的ViewPager的实现

    2022-12-30 19:56:17
  • java连接zookeeper实现zookeeper教程

    2022-09-19 03:04:35
  • IntelliJ IDEA安装目录和设置目录的说明(IntelliJ IDEA快速入门)

    2021-08-16 21:17:08
  • c#程序定期把内存信息记录到log日志示例

    2022-01-11 16:33:31
  • MyBatis插入Insert、InsertSelective的区别及使用心得

    2023-08-25 04:34:28
  • asp之家 软件编程 m.aspxhome.com