iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >Java中用户线程与守护线程如何使用
  • 804
分享到

Java中用户线程与守护线程如何使用

2023-06-30 14:06:16 804人浏览 薄情痞子
摘要

本篇内容介绍了“Java中用户线程与守护线程如何使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1.默认用户线程Java 语言中无论是线程

本篇内容介绍了“Java中用户线程与守护线程如何使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

    1.默认用户线程

    Java 语言中无论是线程还是线程池,默认都是用户线程,因此用户线程也被成为普通线程。

    以线程为例,想要查看线程是否为守护线程只需通过调用 isDaemon() 方法查询即可,如果查询的值为 false 则表示不为守护线程,自然也就属于用户线程了,

    如下代码所示:

    public static void main(String[] args) throws InterruptedException {    Thread thread = new Thread(new Runnable() {        @Override        public void run() {            System.out.println("我是子线程");        }    });    System.out.println("子线程==守护线程:" + thread.isDaemon());    System.out.println("主线程==守护线程:" + Thread.currentThread().isDaemon());}

    以上程序的执行结果为: 

    Java中用户线程与守护线程如何使用

     从上述结果可以看出,默认情况下主线程和创建的新线程都为用户线程

    PS:Thread.currentThread() 的意思是获取执行当前代码的线程实例。

    2.主动修改为守护线程

    守护线程(Daemon Thread)也被称之为后台线程或服务线程,守护线程是为用户线程服务的,当程序中的用户线程全部执行结束之后,守护线程也会跟随结束。

    守护线程的角色就像“服务员”,而用户线程的角色就像“顾客”,当“顾客”全部走了之后(全部执行结束),那“服务员”(守护线程)也就没有了存在的意义,所以当一个程序中的全部用户线程都结束执行之后,那么无论守护线程是否还在工作都会随着用户线程一块结束,整个程序也会随之结束运行。

    那如何将默认的用户线程修改为守护线程呢?

    这个问题要分为两种情况来回答,首先如果是线程,则可以通过设置 setDaemon(true) 方法将用户线程直接修改为守护线程,而如果是线程池则需要通过 ThreadFactory 将线程池中的每个线程都为守护线程才行,接下来我们分别来实现一下。

    2.1 设置线程为守护线程

    如果使用的是线程,可以通过 setDaemon(true) 方法将线程类型更改为守护线程,如下代码所示:

     public static void main(String[] args) throws InterruptedException {     Thread thread = new Thread(new Runnable() {         @Override         public void run() {             System.out.println("我是子线程");         }     });     // 设置子线程为守护线程     thread.setDaemon(true);     System.out.println("子线程==守护线程:" + thread.isDaemon());     System.out.println("主线程==守护线程:" + Thread.currentThread().isDaemon()); }

    以上程序的执行结果为: 

    Java中用户线程与守护线程如何使用

    2.2 设置线程池为守护线程

    要把线程池设置为守护线程相对来说麻烦一些,需要将线程池中的所有线程都设置成守护线程,这个时候就需要使用 ThreadFactory 来定义线程池中每个线程的线程类型了,具体实现代码如下:

    // 创建固定个数的线程池ExecutorService threadPool = Executors.newFixedThreadPool(10, new ThreadFactory() {    @Override    public Thread newThread(Runnable r) {        Thread t = new Thread(r);        // 设置线程为守护线程        t.setDaemon(false);        return t;    }});

    如下图所示: 

    Java中用户线程与守护线程如何使用

    如上图所示,可以看出,整个程序中有 10 个守护线程都是我创建的。其他几种创建线程池的设置方式类似,都是通过 ThreadFactory 统一设置的,这里就不一一列举了。

    3.守护线程 VS 用户线程

    通过前面的学习我们可以创建两种不同的线程类型了,那二者有什么差异呢?接下来我们使用一个小示例来看一下。

    下面我们创建一个线程,分别将这个线程设置为用户线程和守护线程,在每个线程中执行一个 for 循环,总共执行 10 次信息打印,每次打印之后休眠 100 毫秒,来观察程序的运行结果。

    3.1 用户线程

    新建的线程默认就是用户线程,因此我们无需对线程进行任何特殊的处理,执行 for 循环即可(总共执行 10 次信息打印,每次打印之后休眠 100 毫秒),实现代码如下:

    public class DaemonExample {    public static void main(String[] args) throws InterruptedException {        Thread thread = new Thread(new Runnable() {            @Override            public void run() {                for (int i = 1; i <= 10; i++) {                    // 打印 i 信息                    System.out.println("i:" + i);                    try {                        // 休眠 100 毫秒                        Thread.sleep(100);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }            }        });        // 启动线程        thread.start();    }}

    以上程序执行结果如下: 

    Java中用户线程与守护线程如何使用

     从上述结果可以看出,当程序执行完 10 次打印之后才会正常结束进程。

    3.2 守护线程

    public class DaemonExample {    public static void main(String[] args) throws InterruptedException {        Thread thread = new Thread(new Runnable() {            @Override            public void run() {                for (int i = 1; i <= 10; i++) {                    // 打印 i 信息                    System.out.println("i:" + i);                    try {                        // 休眠 100 毫秒                        Thread.sleep(100);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }            }        });        // 设置为守护线程        thread.setDaemon(true);        // 启动线程        thread.start();    }}

    以上程序执行结果如下: 

    Java中用户线程与守护线程如何使用

     从上述结果可以看出,当线程设置为守护线程之后,整个程序不会等守护线程 for 循环 10 次之后再进行关闭,而是当主线程结束之后,守护线程只执行了一次循环就结束运行了,由此可以看出守护线程和用户线程的不同。

    3.3 小结

    守护线程是为用户线程服务的,当一个程序中的所有用户线程都执行完成之后程序就会结束运行,程序结束运行时不会管守护线程是否正在运行,由此我们可以看出守护线程在 Java 体系中权重是比较低的。

    4.守护线程注意事项

    守护线程的使用需要注意以下三个问题:

    • 守护线程的设置 setDaemon(true) 必须要放在线程的 start() 之前,否则程序会报错。

    • 在守护线程中创建的所有子线程都是守护线程。

    • 使用 jojn() 方法会等待一个线程执行完,无论此线程是用户线程还是守护线程。

    接下来我们分别演示一下,以上的注意事项。

    4.1 setDaemon 执行顺序

    当我们将 setDaemon(true) 设置在 start() 之后,如下代码所示:

    public static void main(String[] args) throws InterruptedException {    Thread thread = new Thread(new Runnable() {        @Override        public void run() {            for (int i = 1; i <= 10; i++) {                // 打印 i 信息                System.out.println("i:" + i + ",isDaemon:" +                            Thread.currentThread().isDaemon());                try {                    // 休眠 100 毫秒                    Thread.sleep(100);                } catch (InterruptedException e) {                    e.printStackTrace();                }            }        }    });    // 启动线程    thread.start();    // 设置为守护线程    thread.setDaemon(true);}

    以上程序执行结果如下: 

    Java中用户线程与守护线程如何使用

     从上述结果可以看出,当我们将 setDaemon(true) 设置在 start() 之后,不但程序的执行会报错,而且设置的守护线程也不会生效。

    4.2 守护线程的子线程

    public static void main(String[] args) throws InterruptedException {    Thread thread = new Thread(new Runnable() {        @Override        public void run() {            Thread thread2 = new Thread(new Runnable() {                @Override                public void run() {                }            });            System.out.println("守护线程的子线程 thread2 isDaemon:" +                              thread2.isDaemon());        }    });    // 设置为守护线程    thread.setDaemon(true);    // 启动线程    thread.start();    Thread.sleep(1000);}

    以上程序执行结果如下: 

    Java中用户线程与守护线程如何使用

     从上述结果可以看出,守护线程中创建的子线程,默认情况下也属于守护线程

    4.3 join 与守护线程

    通过 3.2 部分的内容我们可以看出,默认情况下程序结束并不会等待守护线程执行完,而当我们调用线程的等待方法 join() 时,执行的结果就会和 3.2 的结果有所不同,下面我们一起来看吧,

    示例代码如下:

    public static void main(String[] args) throws InterruptedException {    Thread thread = new Thread(new Runnable() {        @Override        public void run() {            for (int i = 1; i <= 10; i++) {                // 打印 i 信息                System.out.println("i:" + i);                try {                    // 休眠 100 毫秒                    Thread.sleep(100);                } catch (InterruptedException e) {                    e.printStackTrace();                }            }        }    });    // 设置为守护线程    thread.setDaemon(true);    // 启动线程    thread.start();    // 等待线程执行完    thread.join();    System.out.println("子线程==守护线程:" + thread.isDaemon());    System.out.println("主线程==守护线程:" + Thread.currentThread().isDaemon());}

    以上程序执行结果如下: 

    Java中用户线程与守护线程如何使用

     通过上述结果我们可以看出,即使是守护线程,当程序中调用 join() 方法时,程序依然会等待守护线程执行完成之后再结束进程。

    5.守护线程应用场景

    守护线程的典型应用场景就是垃圾回收线程,当然还有一些场景也非常适合使用守护线程,比如服务器端的健康检测功能,对于一个服务器来说健康检测功能属于非核心非主流的服务业务,像这种为了主要业务服务的业务功能就非常合适使用守护线程,当程序中的主要业务都执行完成之后,服务业务也会跟随者一起销毁。

    6.守护线程的执行优先级

    首先来说,线程的类型(用户线程或守护线程)并不影响线程执行的优先级,如下代码所示,定义一个用户线程和守护线程,分别执行 10 万次循环,通过观察最后的打印结果来确认线程类型对程序执行优先级的影响。

    public class DaemonExample {    private static final int count = 100000;    public static void main(String[] args) throws InterruptedException {        // 定义任务        Runnable runnable = new Runnable() {            @Override            public void run() {                for (int i = 0; i < count; i++) {                    System.out.println("执行线程:" + Thread.currentThread().getName());                }            }        };        // 创建守护线程 t1        Thread t1 = new Thread(runnable, "t1");        // 设置为守护线程        t1.setDaemon(true);        // 启动线程        t1.start();        // 创建用户线程 t2        Thread t2 = new Thread(runnable, "t2");        // 启动线程        t2.start();    }}

    以上程序执行结果如下: 

    Java中用户线程与守护线程如何使用

     通过上述结果可以看出,线程的类型不管是守护线程还是用户线程对程序执行的优先级是没有任何影响的,而当我们将 t2 的优先级调整为最大时,整个程序的运行结果就完全不同了,

    如下代码所示:

    public class DaemonExample {    private static final int count = 100000;    public static void main(String[] args) throws InterruptedException {        // 定义任务        Runnable runnable = new Runnable() {            @Override            public void run() {                for (int i = 0; i < count; i++) {                    System.out.println("执行线程:" + Thread.currentThread().getName());                }            }        };        // 创建守护线程 t1        Thread t1 = new Thread(runnable, "t1");        // 设置为守护线程        t1.setDaemon(true);        // 启动线程        t1.start();        // 创建用户线程 t2        Thread t2 = new Thread(runnable, "t2");        // 设置 t2 的优先级为最高        t2.setPriority(Thread.MAX_PRIORITY);        // 启动线程        t2.start();    }}

    以上程序执行结果如下: 

    Java中用户线程与守护线程如何使用

    00000000 通过上述的结果可以看出,程序的类型和程序执行的优先级是没有任何关系,当新创建的线程默认的优先级都是 5 时,无论是守护线程还是用户线程,它们执行的优先级都是相同的,当将二者的优先级设置不同时,执行的结果也会随之改变(优先级设置的越高,最早被执行的概率也越大)。

    “Java中用户线程与守护线程如何使用”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

    --结束END--

    本文标题: Java中用户线程与守护线程如何使用

    本文链接: https://www.lsjlt.com/news/329713.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    本篇文章演示代码以及资料文档资料下载

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档
    猜你喜欢
    • Java中用户线程与守护线程如何使用
      本篇内容介绍了“Java中用户线程与守护线程如何使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1.默认用户线程Java 语言中无论是线程...
      99+
      2023-06-30
    • Java中用户线程与守护线程的使用区别
      目录1.默认用户线程2.主动修改为守护线程2.1 设置线程为守护线程2.2 设置线程池为守护线程3.守护线程 VS 用户线程3.1 用户线程3.2 守护线程3.3 小结4.守护线程注...
      99+
      2024-04-02
    • Java守护线程和用户线程的区别
      目录守护线程定义创建守护线程将线程池设置为守护线程守护线程 VS 用户线程用户线程守护线程守护线程注意事项总结前言: 在 Java 语言中,线程分为两类:用户线程和守护线程,默认情况...
      99+
      2024-04-02
    • python浅析守护线程与非守护线程的区别与使用
      目录什么是守护线程非守护线程守护线程什么是守护线程 当主线程执行结束后,所有 在运行的子线程都 直接结束,不管子任务是否完成很多语言的 垃圾收集器 就运用了 守护线程,去回收程序不再...
      99+
      2024-04-02
    • Java中用户线程和守护线程有什么区别
      这篇文章给大家分享的是有关Java中用户线程和守护线程有什么区别的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。在 Java  语言中线程分为两类:用户线程和守护线程,而二者之间的区别却鲜有人知,所以本文...
      99+
      2023-06-15
    • java中守护线程与非守护线程的区别有什么
      这篇文章将为大家详细讲解有关java中守护线程与非守护线程的区别有什么,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。守护线程并非虚拟机内部可以提供,用户也可以自行的设定守护线程,方法:pub...
      99+
      2023-05-31
      java 守护线程 非守护线程
    • Java中守护线程和用户线程的区别有哪些
      这篇文章主要介绍Java中守护线程和用户线程的区别有哪些,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!常用的java框架有哪些1.SpringMVC,Spring Web MVC是一种基于Java的实现了Web MV...
      99+
      2023-06-14
    • Java中守护线程介绍及使用
      目录一、什么是守护线程二、为什么需要守护线程三、如何使用注意:总结一、什么是守护线程 在说守护线程之前,我们先说一下什么是用户线程。 用户线程:我们平常创建的普通线程。守护线程(即 ...
      99+
      2024-04-02
    • 怎么在java中使用守护线程
      这期内容当中小编将会给大家带来有关怎么在java中使用守护线程,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Java的特点有哪些Java的特点有哪些1.Java语言作为静态面向对象编程语言的代表,实现了面...
      99+
      2023-06-14
    • java高并发的用户线程和守护线程详解
      目录程序只有守护线程时,系统会自动退出设置守护线程,需要在start()方法之前进行线程daemon的默认值总结守护线程是一种特殊的线程,在后台默默地完成一些系统性的服务,比如垃圾回...
      99+
      2024-04-02
    • 如何守护Java项目中的线程
      如何守护Java项目中的线程?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。       守护线程并非虚拟机内部可以提供,...
      99+
      2023-05-31
      java 线程守护 ava
    • java守护线程怎么应用
      Java守护线程是指在后台提供一种通用服务的线程,并且在所有非守护线程结束时自动退出。守护线程通常用于执行一些背景任务,如垃圾回收、...
      99+
      2023-10-27
      java
    • 怎么理解java高并发的用户线程和守护线程
      这篇文章主要讲解了“怎么理解java高并发的用户线程和守护线程”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么理解java高并发的用户线程和守护线程”吧!守护线程是一种特殊的线程,在后台默...
      99+
      2023-06-25
    • 如何进行Java中守护线程的分析及使用
      这篇文章跟大家分析一下“如何进行Java中守护线程的分析及使用”。内容详细易懂,对“如何进行Java中守护线程的分析及使用”感兴趣的朋友可以跟着小编的思路慢慢深入来阅读一下,希望阅读后能够对大家有所帮助。下面跟着小编一起深入学习“如何进行J...
      99+
      2023-06-26
    • Java中的守护线程问题
      目录守护线程在Java中有两类线程守护线程与用户线程的区别1 定义和概述2 使用守护线程3 测试案例4 注意事项守护线程 在Java中有两类线程 User Thread(用户线程)D...
      99+
      2022-11-13
      Java线程 守护线程 Java守护线程
    • java中设置线程为守护线程的方法
      这篇文章主要介绍java中设置线程为守护线程的方法,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!Java的特点有哪些Java的特点有哪些1.Java语言作为静态面向对象编程语言的代表,实现了面向对象理论,允许程序员以...
      99+
      2023-06-14
    • Python之守护线程与锁
        # 守护线程随着子线程结束而结束,与守护进程不一样--守护进程随着主进程代码执行完毕而结束  # from threading import Thread  # import time  #  # def func1():  # whi...
      99+
      2023-01-31
      线程 Python
    • 如何在python中创建守护线程
      这期内容当中小编将会给大家带来有关如何在python中创建守护线程,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。python的五大特点是什么python的五大特点:1.简单易学,开发程序时,专注的是解决问...
      99+
      2023-06-14
    • java怎么设置守护线程
      在Java中,可以通过`Thread.setDaemon(true)`方法将线程设置为守护线程。守护线程是一种特殊的线程,当所有非守...
      99+
      2023-08-20
      java
    • Java语言守护线程DaemonThread使用示例详解
      目录守护线程用户线程设为守护线程守护线程 在Java语言中有两类线程:用户线程和守护线程。我们通俗的讲,任意一个守护线程都是整个JVM中所有线程的"大管家";只要...
      99+
      2022-11-13
      Java 守护线程Daemon Thread Java 守护线程
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作