• Java 守护线程


    在 Java 并发编程实践或看涉及到 Java 并发相关的代码时,经常会遇到一些线程(比如做 metrics 统计的线程等)会通过 setDaemon() 方法设置将该线程的 daemon 变量设置为 True,也就是将这个线程设置为了守护线程(daemon thread),那么什么是守护线程呢?或者说守护线程与非守护线程(普通线程)的区别在什么地方呢?这个就是本文主要讲述的内容。

    守护线程

    一般来说,Java 中的线程可以分为两种:守护线程和普通线程。在 JVM 刚启动时,它创建的所有线程,除了主线程(main thread)外,其他的线程都是守护线程(比如:垃圾收集器、以及其他执行辅助操作的线程)。

    当创建一个新线程时,新线程将会继承它线程的守护状态,默认情况下,主线程创建的所有线程都是普通线程。

    什么情况下会需要守护线程呢?一般情况下是,当我们希望创建一个线程来执行一些辅助的工作,但是又不希望这个线程阻碍 JVM 的关闭,在这种情况下,我们就需要使用守护线程了。

    守护线程的作用

    守护线程与普通线程唯一的区别是:当线程退出时,JVM 会检查其他正在运行的线程,如果这些线程都是守护线程,那么 JVM 会正常退出操作,但是如果有普通线程还在运行,JVM 是不会执行退出操作的。当 JVM 退出时,所有仍然存在的守护线程都将被抛弃,既不会执行 finally 部分的代码,也不会执行 stack unwound 操作,JVM 会直接退出。

    When the JVM halts any remaining daemon threads are abandoned:

    1. finally blocks are not executed,
    2. stacks are not unwound - the JVM just exits.

    下面有个小示例,来自 What is a daemon thread in Java?,代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    public class DaemonTest {

    public static void main(String[] args) {
    new WorkerThread().start();

    try {
    Thread.sleep(7500);
    } catch (InterruptedException e) {
    // handle here exception
    }

    System.out.println("Main Thread ending");
    }

    }

    class WorkerThread extends Thread {

    public WorkerThread() {
    // When false, (i.e. when it's a user thread), the Worker thread continues to run.
    // When true, (i.e. when it's a daemon thread), the Worker thread terminates when the main thread terminates.
    setDaemon(false);
    }

    public void run() {
    int count = 0;

    while (true) {
    System.out.println("Hello from Worker " + count++);

    try {
    sleep(5000);
    } catch (InterruptedException e) {
    // handle exception here
    }
    }
    }
    }

    当为普通线程时,输出如下:

    Hello from Worker 0
    Hello from Worker 1
    Main Thread ending
    Hello from Worker 2
    Hello from Worker 3
    Hello from Worker 4
    Hello from Worker 5
    ....

    也就是说,此时即使主线程执行完了,JVM 也会等待 WorkerThread 执行完毕才会退出,而如果将该线程设置守护线程的话,输出如下:

    Hello from Worker 0
    Hello from Worker 1
    Main Thread ending

    在 main 线程执行完毕后,JVM 进程就退出了,不会 care WorkerThread 线程是否执行完毕。

    参考:

    文章来源:https://matt33.com/2018/07/07/java-daemon-thread/

  • 相关阅读:
    手把手实战:eclipse 搭建 SpringMvc 框架环境
    解决eclipse中Tomcat服务器的server location选项不能修改的问题
    如何解决JSP页面顶端报错 The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path
    第二课 --- git的(管理修改和撤销修改、删除文件)
    第二课 ---git时光穿梭(版本回退)
    第一课——git的简介和基本使用
    001——使用composer安装ThinkPHP5
    微信小程序中对于变量的定义
    微信小程序onLaunch修改globalData的值
    7——ThinkPhp中的响应和重定向:
  • 原文地址:https://www.cnblogs.com/fanfuhu/p/12315468.html
Copyright © 2020-2023  润新知