【java 多线程】守护线程与非守护线程的详解

Java多线程:守护线程与非守护线程的详解

什么是守护线程?

在Java多线程中,守护线程是一种在后台运行的线程,它不会阻止程序的结束,也不会执行任何没有被其他非守护线程阻止的操作。

换句话说,当程序中最后一个非守护线程结束时,JVM会强制退出来,即使守护线程还在运行。

如何创建守护线程?

可以通过Thread类的setDaemon()方法来创建守护线程,示例如下:

Thread daemonThread = new Thread(new Runnable() {
    @Override
    public void run() {
        while (true) {
            System.out.println("I'm a daemon thread!");
        }
    }
});
daemonThread.setDaemon(true);
daemonThread.start();

在上述代码中,创建了一个无限循环的守护线程,当程序中最后一个非守护线程结束时,守护线程也将停止运行。

如何创建非守护线程?

非守护线程是线程默认创建的类型。如果一个线程没有被设置为守护线程,那么它就是非守护线程。

示例如下:

Thread nonDaemonThread = new Thread(new Runnable() {
    @Override
    public void run() {
        while (true) {
            System.out.println("I'm a non-daemon thread!");
        }
    }
});
nonDaemonThread.start();

在上述代码中,创建了一个无限循环的非守护线程。

守护线程和非守护线程的区别

主要区别在于程序结束时守护线程和非守护线程的行为不同。

当程序中最后一个非守护线程结束时,JVM会强制退出来,即使守护线程还在运行。而非守护线程执行完它的任务后,程序才会退出。

此外,守护线程还有一个特点,它不会阻止JVM的正常关闭。

示例说明1:使用守护线程实现自动保存功能

public class AutoSaveThread extends Thread {

    private boolean changed = false;

    public void setChanged() {
        this.changed = true;
    }

    @Override
    public void run() {
        while (true) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (changed) {
                System.out.println("自动保存");
                changed = false;
            }
        }
    }

    public static void main(String[] args) throws Exception {
        AutoSaveThread autoSaveThread = new AutoSaveThread();
        autoSaveThread.setDaemon(true);
        autoSaveThread.start();

        for (int i = 0; i < 5; i++) {
            System.out.println("Main thread working...");
            Thread.sleep(1000);
            autoSaveThread.setChanged();
        }
    }
}

在上述代码中,创建了一个存储是否发生变更的布尔值变量changed的AutoSaveThread守护线程。在运行时,守护线程每秒检查一次是否有发生变更,有变更则自动保存。在主线程中执行5次循环时,每次循环后都将changed设为true,以用于守护线程的条件判断。

运行该程序时,即使主线程已经结束,但守护线程会一直运行下去。

示例说明2:使用非守护线程下载文件

public class DownloadThread implements Runnable {

    private String url;
    private String fileName;

    public DownloadThread(String url, String fileName) {
        this.url = url;
        this.fileName = fileName;
    }

    @Override
    public void run() {
        try {
            URL downLoadUrl = new URL(url);
            URLConnection conn = downLoadUrl.openConnection();
            InputStream is = conn.getInputStream();

            FileOutputStream fos = new FileOutputStream(fileName);
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = is.read(buffer)) != -1) {
                fos.write(buffer, 0, len);
            }
            fos.close();
            is.close();

            System.out.println(fileName + " 下载完成!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        new Thread(new DownloadThread("http://cdn.npm.taobao.org/dist/node/v10.15.1/node-v10.15.1.pkg", "node-v10.15.1.pkg")).start();
        new Thread(new DownloadThread("http://sw.bos.baidu.com/sw-search-sp/software/8c18ae9d1d1e7/SogouInput_mac_10.1.0.1338.dmg", "SogouInput_mac_10.1.0.1338.dmg")).start();
    }
}

在上述代码中,创建了一个非守护线程DownloadThread来实现下载文件。在main方法中,同时执行了两个DownloadThread实例,在两个线程中分别下载了node.js和搜狗输入法的安装包。

在下载完成后,程序仍然不会退出,因为这里使用的是非守护线程。

总结

通过本文,我们详细讲解了Java多线程中守护线程和非守护线程的概念和用法,并给出了多个示例。掌握了守护线程和非守护线程的使用方法,可以帮助我们更好的进行多线程编程。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:【java 多线程】守护线程与非守护线程的详解 - Python技术站

(0)
上一篇 2023年5月17日
下一篇 2023年5月17日

相关文章

  • C#网络编程基础之进程和线程详解

    C#网络编程基础之进程和线程详解 什么是进程和线程? 在计算机中,程序的执行过程是由进程和线程来完成的。进程是程序的一次执行过程,是操作系统对正在运行的程序的一种抽象,是分配和管理系统资源的最小单位。一个进程拥有一个独立的虚拟地址空间、堆、栈、文件句柄等资源。而线程是指进程中的一个执行单元,每个线程都有自己的执行路径、局部变量、运行状态等,是CPU调度的基本…

    多线程 2023年5月16日
    00
  • Golang CSP并发机制及使用模型

    Golang CSP并发机制及使用模型 什么是Golang的CSP并发机制 CSP 并发模型是指 Communicating Sequential Processes,通信顺序进程,这一思想由 Tony Hoare 在 1978 年提出,是以通信的方式协调不同的进程,这与传统的线程模型不同,线程是通过锁、信号等方式互相协作,而 CSP 是通过通信来达到互斥与…

    多线程 2023年5月17日
    00
  • golang并发ping主机的方法

    首先我们需要了解一下”并发ping主机的方法”的概念。 将多个ping请求并发地发送给多个主机,可以达到加快检测速度,提高并发性能的目的。在golang中,可以使用goroutine和channel等机制来实现并发ping主机的方法。 以下是一份完整的攻略: 1. 准备工作 准备一个可以进行ping测试的服务器,并确保目标主机有响应。 在golang中,需要…

    多线程 2023年5月17日
    00
  • 基于Redis实现分布式应用限流的方法

    基于Redis实现分布式应用限流的方法 什么是限流 限流是一种应对高并发的常见手段。在应用中有些场景,比如短时间内某个接口请求过多、恶意攻击等,这时候我们可能想要限制最大的请求并发数,限制起始频率和限制持续时间等。 基于Redis的分布式限流 基于Redis的分布式限流是应用中比较常见的方案。Redis实现分布式限流通常采用令牌桶算法,而基于Redis实现分…

    多线程 2023年5月17日
    00
  • Java多线程的具体介绍与使用笔记小结

    Java多线程的具体介绍与使用 什么是多线程 多线程指的是在同一时间内,CPU运行多个线程来完成不同的任务。在Java中,每个线程都是独立的执行路径,使得程序可以分配更多的资源去处理其他任务,并确保线程之间的相互独立。 多线程的优点 多线程的优点主要体现在以下几个方面: 实现并发编程,提升代码的效率和性能; 减少线程资源的竞争,提高程序的响应性和稳定性; 分…

    多线程 2023年5月17日
    00
  • 聊聊java多线程创建方式及线程安全问题

    那么让我们来聊聊Java多线程创建方式及线程安全问题的完整攻略。 1. Java多线程的创建方式 Java中创建多线程有两种方式,一种是继承Thread类,另一种是实现Runnable接口。 1.1 继承Thread类 示例代码如下: class MyThread extends Thread { public void run() { System.out…

    多线程 2023年5月16日
    00
  • Linux C中多线程与volatile变量

    针对该问题,我为您提供如下完整讲解: Linux C中多线程与volatile变量 一、volatile变量的概念 在C语言中,volatile是一种类型限定符,通常用于修饰容易发生变化、被多线程访问或外部程序访问等的变量。该限定符告诉编译器不要对变量进行优化,每次使用变量都必须从内存中读取该变量的值,而不是从CPU寄存器中读取,保证多线程或外部程序对该变量…

    多线程 2023年5月16日
    00
  • Redis服务之高可用组件sentinel详解

    Redis服务之高可用组件sentinel详解 什么是Redis Sentinel? Redis Sentinel 是 Redis 官方提供的一种高可用性解决方案,它可以对 Redis 主从集群进行自动的故障检测和故障转移。 当 Redis 主节点出现故障时,Sentinel 可以自动地将其中一个从节点切换为新的主节点,继续处理客户端请求。这一过程的自动化可…

    多线程 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部