【JAVA】深入理解守护线程与非守护线程:概念、应用及示例

news2025/2/27 1:40:32

在这里插入图片描述

文章目录

  • 介绍
    • 1. 线程的基础知识
    • 2. 守护线程与非守护线程
      • 2.1 什么是守护线程?
        • 特点:
      • 2.2 什么是非守护线程?
        • 特点:
    • 3. 为什么需要守护线程?
      • 示例:后台任务处理
      • 示例:日志记录
    • 4. 非守护线程的应用场景
      • 示例:数据库连接处理
    • 5. 守护线程与非守护线程的对比
    • 6. 总结

更多相关内容可查看

介绍

在多线程编程中,线程的管理是至关重要的。Java 提供了两种主要的线程类型:守护线程和非守护线程。理解它们的区别以及如何在实际应用中使用它们,对编写高效和稳定的程序至关重要。本文将深入探讨这两种线程的概念、应用场景,并通过实际代码示例帮助你掌握如何使用它们。

1. 线程的基础知识

线程是进程中的一个执行单元,一个进程可以包含多个线程。线程的基本生命周期包括:

  • 新建(New):线程被创建,但尚未启动。
  • 就绪(Runnable):线程已准备好运行,并等待 CPU 调度。
  • 运行(Running):线程正在 CPU 上执行。
  • 阻塞(Blocked):线程因等待某些资源或条件而被阻塞。
  • 死亡(Terminated):线程执行完毕或被终止。

2. 守护线程与非守护线程

2.1 什么是守护线程?

守护线程是一种特殊类型的线程,它的存在不会阻止 JVM 退出。守护线程一般用于后台任务,如垃圾回收、监控任务等。当所有非守护线程都结束时,JVM 会退出,即使守护线程仍在运行。

特点:
  • 生命周期:守护线程的生命周期依赖于 JVM。当所有非守护线程完成后,JVM 会终止守护线程。
  • 用途:适用于后台处理,如定期清理操作、监控服务等。

2.2 什么是非守护线程?

非守护线程是普通线程,它会阻止 JVM 退出,直到它们完成执行。这类线程用于执行实际的应用任务,保证任务的完整性和稳定性。

特点:
  • 生命周期:非守护线程的生命周期独立于 JVM。JVM 会等到所有非守护线程完成后才退出。
  • 用途:适用于需要保证任务完成的场景,如数据库操作、用户请求处理等。

3. 为什么需要守护线程?

守护线程通常用于后台处理,避免了后台任务阻塞程序退出的情况。它们在完成任务时会自动结束,适合用于不影响程序主逻辑的服务。

示例:后台任务处理

假设我们有一个 Web 服务器,需要定期清理过期的会话数据。我们可以使用守护线程来实现这个功能,这样即使主线程结束,后台任务仍然可以在守护线程中运行。

public class DaemonThreadExample {
    public static void main(String[] args) {
        Thread cleanupThread = new Thread(() -> {
            while (true) {
                System.out.println("Cleaning up expired sessions...");
                try {
                    Thread.sleep(10000); // 每 10 秒执行一次清理
                } catch (InterruptedException e) {
                    System.err.println("Cleanup thread interrupted");
                }
            }
        });

        cleanupThread.setDaemon(true); // 设置为守护线程
        cleanupThread.start();

        System.out.println("Main thread ending...");
        // 主线程结束后,JVM 会退出,守护线程也会被终止
    }
}

在上述代码中,cleanupThread 被设置为守护线程,它将在后台运行,定期执行清理任务。主线程结束时,JVM 会终止守护线程。

示例:日志记录

假设我们有一个日志记录的需求,我们希望将程序中发生的一些重要事件记录到文件中。为了避免日志记录的操作影响到主业务逻辑的执行,我们可以将日志记录的线程设为守护线程。

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

public class DaemonThreadExample {
    
    public static void main(String[] args) {
        // 创建并启动日志记录的守护线程
        Thread logThread = new Thread(new LogTask());
        logThread.setDaemon(true); // 将线程设为守护线程
        logThread.start();
        
        // 主业务逻辑
        try {
            for (int i = 0; i < 5; i++) {
                System.out.println("Main thread is working: iteration " + i);
                Thread.sleep(1000); // 模拟主线程的工作
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        System.out.println("Main thread finished, program will exit soon.");
    }
    
    // 日志记录任务
    static class LogTask implements Runnable {
        @Override
        public void run() {
            try (PrintWriter writer = new PrintWriter(new FileWriter("log.txt", true))) {
                while (true) {
                    writer.println("Logging at " + System.currentTimeMillis());
                    writer.flush();
                    try {
                        Thread.sleep(2000); // 每2秒记录一次日志
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        break;
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

4. 非守护线程的应用场景

非守护线程用于执行核心业务逻辑,确保任务能够完整执行。比如数据库连接操作、文件处理等都需要在任务完成后才退出。

示例:数据库连接处理

假设我们有一个任务,需要打开一个数据库连接进行长时间的操作。我们可以使用非守护线程来确保连接在任务完成后正确关闭。

public class NonDaemonThreadExample {
    public static void main(String[] args) {
        Thread dbTaskThread = new Thread(() -> {
            System.out.println("Opening database connection...");
            try {
                // 模拟数据库操作
                Thread.sleep(15000); // 操作时间为 15 秒
                System.out.println("Database operation complete.");
            } catch (InterruptedException e) {
                System.err.println("Database task interrupted");
            } finally {
                System.out.println("Closing database connection...");
            }
        });

        dbTaskThread.start();

        try {
            dbTaskThread.join(); // 确保主线程等待 dbTaskThread 完成
        } catch (InterruptedException e) {
            System.err.println("Main thread interrupted");
        }

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

在这个示例中,dbTaskThread 是一个非守护线程。主线程调用 join() 方法,确保在主线程退出之前,dbTaskThread 完成其数据库操作并关闭连接。

5. 守护线程与非守护线程的对比

特性守护线程非守护线程
生命周期JVM 退出时自动结束直到任务完成或被显式终止
适用场景背景任务、定时任务需要确保完成的核心业务任务
影响不会阻止 JVM 退出会阻止 JVM 退出,直到线程完成

6. 总结

守护线程和非守护线程各有其适用场景。守护线程适合后台服务任务,不会阻止 JVM 退出,而非守护线程适用于需要确保完成的任务。在编写多线程应用时,合理选择和使用这两种线程类型,可以提升程序的稳定性和性能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2040794.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Scrapy 项目部署问题及解决方案

部署 Scrapy 项目时可能会遇到一些常见问题。以下是几个常见的部署问题及其解决方案&#xff1a; 1、依赖问题 问题&#xff1a;部署后爬虫运行失败&#xff0c;通常是由于缺少依赖库。 2、配置问题 问题&#xff1a;爬虫在部署环境中无法正常运行&#xff0c;可能是由于配…

stm32智能颜色送餐小车(openmv二维码识别+颜色识别+oled显示)

大家好啊&#xff0c;我是情谊&#xff0c;今天我们来介绍一下我最近设计的stm32产品&#xff0c;我们在今年七月份的时候参加了光电设计大赛&#xff0c;我们小队使用的就是stm32的智能送餐小车&#xff0c;虽然止步于省赛&#xff0c;但是还是一次成长的经验吧&#xff0c;那…

深度学习基础之反向传播算法

目录 原理与过程 1. 前向传播&#xff08;Forward Pass&#xff09; 2. 计算误差&#xff08;Error Calculation&#xff09; 3. 反向传播&#xff08;Backpropagation&#xff09; 4. 参数更新&#xff08;Parameter Update&#xff09; 应用与实例 总结 反向传播算法…

1秒出图,全球最快的开源Stable Diffusion出炉

前言 OneFlow 将 Stable Diffusion 的推理性能推向了一个全新的 SOTA。 第一辆汽车诞生之初&#xff0c;时速只有 16 公里&#xff0c;甚至不如马车跑得快&#xff0c;很长一段时间&#xff0c;汽车尴尬地像一种“很酷的玩具”。人工智能作图的出现也是如此。 AI 作图一开始的…

大数据面试SQL(八):求连续段的起始位置和结束位置

文章目录 求连续段的起始位置和结束位置 一、题目 二、分析 三、SQL实战 四、样例数据参考 求连续段的起始位置和结束位置 一、题目 有一张表t2_id记录了id&#xff0c;id不重复&#xff0c;但是会存在间断&#xff0c;求出连续段的起始位置和结束位置。 样例数据&…

两个若依系统,不能同时登录问题解决方案

原因&#xff1a; 问题根源在于两个独立的系统&#xff08;A系统与B系统&#xff09;共享了同一cookie键名来存储各自用户的认证令牌&#xff08;token&#xff09;。这种设计导致了以下情形&#xff1a; 当用户在A系统登录后&#xff0c;一个token被存储在cookie中&#xff0…

【LeetCode每日一题】——623.在二叉树中增加一行

文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【题目提示】七【解题思路】八【时间频度】九【代码实现】十【提交结果】 一【题目类别】 广度优先遍历 二【题目难度】 中等 三【题目编号】 623.在二叉树中增加一行 四【题目描述】…

c语言学习,memset()函数分析

1&#xff1a;memset() 函数说明&#xff1a; 将字符c&#xff08;unsigned char&#xff09;复制到str字符串的前n个字符 2&#xff1a;函数原型&#xff1a; void * memset(void * str,int c,size_t n) 3&#xff1a;函数参数&#xff1a; 参数str要填充的指针,c 要设置的值…

2024下半年EI学术会议一览表

2024下半年将举办多个重要的EI学术会议&#xff0c;涵盖了从机器视觉、图像处理与影像技术到感知技术、绿色通信、计算机、大数据与人工智能等多个领域。 2024下半年EI学术会议一览表 第二届机器视觉、图像处理与影像技术国际会议&#xff08;MVIPIT 2024&#xff09;将于2024…

threejs webgl效果 功能特效

雷达效果 ​飘扬的红旗 光柱效果 OD线 下雪 下雨 光墙效果 能源球 烟火效果 threejs烟花效果 光圈效果 threejs 光圈 波动 function initScene() {scene new THREE.Scene();}function initCamera() {camera new THREE.PerspectiveCamera(45, window.innerWidth / window.inne…

培训学校课程管理系统-计算机毕设Java|springboot实战项目

&#x1f34a;作者&#xff1a;计算机毕设残哥 &#x1f34a;简介&#xff1a;毕业后就一直专业从事计算机软件程序开发&#xff0c;至今也有8年工作经验。擅长Java、Python、微信小程序、安卓、大数据、PHP、.NET|C#、Golang等。 擅长&#xff1a;按照需求定制化开发项目、 源…

MiniCPM-V 2.6 面壁“小钢炮”,多图、视频理解多模态模型,部署和推理实战教程

MiniCPM-V 2.6是清华和面壁智能最新发布的多模态模型&#xff0c;亦称面壁“小钢炮”&#xff0c;它是 MiniCPM-V 系列中最新、性能最佳的模型。该模型基于 SigLip-400M 和 Qwen2-7B 构建&#xff0c;仅 8B 参数&#xff0c;但却取得 20B 以下单图、多图、视频理解 3 SOTA 成绩…

leetcode300. 最长递增子序列,动态规划附状态转移方程

leetcode300. 最长递增子序列 给你一个整数数组 nums &#xff0c;找到其中最长严格递增子序列的长度。 子序列 是由数组派生而来的序列&#xff0c;删除&#xff08;或不删除&#xff09;数组中的元素而不改变其余元素的顺序。例如&#xff0c;[3,6,2,7] 是数组 [0,3,1,6,2,2…

【扩散模型(七)】Stable Diffusion 3 diffusers 源码详解2 - DiT 与 MMDiT 相关代码(上)

系列文章目录 【扩散模型&#xff08;一&#xff09;】中介绍了 Stable Diffusion 可以被理解为重建分支&#xff08;reconstruction branch&#xff09;和条件分支&#xff08;condition branch&#xff09;【扩散模型&#xff08;二&#xff09;】IP-Adapter 从条件分支的视…

“从零开始的HTML 表格”——WEB开发系列09

HTML 表格是一种用于在网页上组织和显示信息的结构性元素&#xff0c;它能够将数据以行和列的形式呈现&#xff0c;帮助用户更清晰地理解数据关系。表格在展示统计数据、产品列表、日程安排等方面非常实用。 一、HTML 表格的基本结构 HTML 表格用 ​​<table>​​ 标签来…

创意无限!2024年热门视频剪辑软件精选

从专业级电影剪辑工具到简单易用的手机APP&#xff0c;再到集创意与高效于一身的桌面应用&#xff0c;各类剪辑软件如雨后春笋般涌现。本文将带你一窥2024年火热的剪辑视频的软件。 1.福昕视频剪辑 连接直达>>https://www.pdf365.cn/foxit-clip/ 这款视频编辑工具凭…

Oracle 12.2集群搭建遇到ORA-ORA-15227,ORA-15031,ORA-15018问题处理

报错&#xff1a; [FATAL] [DBT-30056] Labeling of disks failed. ORA-15227: could not perform label set/clear operation ORA-15031: disk specification /dev/asmdisk/ocr01 matches no disks [FATAL] [DBT-30002] Disk group OCR creation failed. ORA-15018: diskgrou…

用Python实现9大回归算法详解——03. 岭回归算法

1. 岭回归的基本概念与动机 1.1 为什么使用岭回归&#xff1f; 在线性回归中&#xff0c;当特征之间存在强烈的相关性&#xff08;即多重共线性&#xff09;时&#xff0c;回归系数会变得不稳定&#xff0c;导致模型在新数据上的表现很差。多重共线性会导致普通最小二乘法&am…

stm32f407新建项目工程及烧录

1、新建一个文件夹&#xff0c;打开keil5将项目工程放入文件夹中 2、弹出选择对应型号设备 3、弹出选择对应库 可以看见出现下图&#xff1a;感叹号表示有错 最后如图所示&#xff1a;点击ok就行了 4、创建对应的文件夹存放文件 4、建立main.c 5、添加对应的设置 最后写一个空白…

sp-eric靶机

端口扫描 靶机ip地址为192.168.7.46 目录扫描 访问80端口 拼接访问 /admin.php 发现登录框 测试sql注入&#xff0c;弱口令等&#xff0c;无结果 扫描目录发现了.git文件&#xff0c;存在源码泄漏 将其下载到kali上读取 python2 GitHack.py -u http://192.168.7.180/.git/…