zoukankan      html  css  js  c++  java
  • 什么是守护线程?

    Java线程分为用户线程和守护线程。

    • 守护线程是程序运行的时候在后台提供一种通用服务的线程。所有用户线程停止,进程会停掉所有守护线程,退出程序。
    • Java中把线程设置为守护线程的方法:在 start 线程之前调用线程的 setDaemon(true) 方法。

    注意:

    • setDaemon(true) 必须在 start() 之前设置,否则会抛出IllegalThreadStateException异常,该线程仍默认为用户线程,继续执行
    • 守护线程创建的线程也是守护线程
    • 守护线程不应该访问、写入持久化资源,如文件、数据库,因为它会在任何时间被停止,导致资源未释放、数据写入中断等问题
    package constxiong.concurrency.a008;
    
    /**
     * 测试守护线程
     * @author ConstXiong
     * @date 2019-09-03 12:15:59
     */
    public class TestDaemonThread {
    
        public static void main(String[] args) {
            testDaemonThread();
        }
        
        //
        public static void testDaemonThread() {
            Thread t = new Thread(() -> {
                //创建线程,校验守护线程内创建线程是否为守护线程
                Thread t2 = new Thread(() -> {
                    System.out.println("t2 : " + (Thread.currentThread().isDaemon() ? "守护线程" : "非守护线程"));
                });
                t2.start();
                
                //当所有用户线程执行完,守护线程会被直接杀掉,程序停止运行
                int i = 1;
                while(true) {
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("t : " + (Thread.currentThread().isDaemon() ? "守护线程" : "非守护线程") + " , 执行次数 : " + i);
                    if (i++ >= 10) {
                        break;
                    }
                }
            });
            //setDaemon(true) 必须在 start() 之前设置,否则会抛出IllegalThreadStateException异常,该线程仍默认为用户线程,继续执行
            t.setDaemon(true);
            t.start();
            
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //主线程结束
            System.out.println("主线程结束");
        }
        
    }

    执行结果

    t2 : 守护线程
    t : 守护线程 , 执行次数 : 1
    主线程结束
    t : 守护线程 , 执行次数 : 2

    结论:

    • 上述代码线程t,未打印到 t : daemon thread , time : 10,说明所有用户线程停止,进程会停掉所有守护线程,退出程序
    • 当 t.start(); 放到 t.setDaemon(true);  之前,程序抛出IllegalThreadStateException,t 仍然是用户线程,打印如下
    Exception in thread "main" t2 : 非守护线程
    java.lang.IllegalThreadStateException
        at java.lang.Thread.setDaemon(Thread.java:1359)
        at constxiong.concurrency.a008.TestDaemonThread.testDaemonThread(TestDaemonThread.java:39)
        at constxiong.concurrency.a008.TestDaemonThread.main(TestDaemonThread.java:11)
    t : 非守护线程 , 执行次数 : 1
    t : 非守护线程 , 执行次数 : 2
    t : 非守护线程 , 执行次数 : 3
    t : 非守护线程 , 执行次数 : 4
    t : 非守护线程 , 执行次数 : 5
    t : 非守护线程 , 执行次数 : 6
    t : 非守护线程 , 执行次数 : 7
    t : 非守护线程 , 执行次数 : 8
    t : 非守护线程 , 执行次数 : 9
    t : 非守护线程 , 执行次数 : 10


     


     

    所有资源资源汇总于公众号



     

  • 相关阅读:
    正则表达式获取字符串中html<input>标签指定value值
    [转]利用SqlBulkCopy快速大批量导入数据(SqlBulkCopy强大)
    ASP.NET数据库操作常用类
    response.redirect 和Server.Transfer有什么区别?
    数据驱动的依存句法分析方法简介(一)
    C#序列化问题
    MSSQL 标量函数
    事件和委托问题转
    Copy指定目录下的所有文件到新位置
    页面指定播放视频
  • 原文地址:https://www.cnblogs.com/ConstXiong/p/11939739.html
Copyright © 2011-2022 走看看