谈谈springboot里面的守护线程与本地线程

简介: 【4月更文挑战第18天】在Spring Boot中,线程的概念同Java标准线程模型一致,即区分为守护线程和用户线程。Spring Boot本身并不直接提供创建守护线程或用户线程的特殊机制,但它允许你通过标准Java方式或者利用Spring的框架特性来管理这些线程

在Spring Boot中,线程的概念同Java标准线程模型一致,即区分为守护线程和用户线程。Spring Boot本身并不直接提供创建守护线程或用户线程的特殊机制,但它允许你通过标准Java方式或者利用Spring的框架特性来管理这些线程。

Spring Boot中的线程使用场景

在Spring Boot应用中,线程常用于以下几个场景:

  1. 异步处理:通过@Async注解,可以轻松地实现方法的异步执行。
  2. 定时任务:使用@Scheduled注解来创建定期执行的任务。
  3. 自定义线程池:可以配置ThreadPoolTaskExecutorThreadPoolTaskScheduler来更细粒度地控制线程的行为和生命周期。

守护线程和用户线程的应用

在Spring Boot中,如果你需要创建并管理自己的线程(无论是守护线程还是用户线程),可以通过直接使用Java的Thread类来实现,或者更常见的做法是使用Spring的任务执行器(Executor)。

  1. 设置守护线程
  • 在Spring Boot中,如果创建线程或线程池,可以显式地设置线程是否为守护线程。这主要通过配置线程工厂来实现,例如使用ConcurrentTaskExecutor配置:

java复制代码

@Bean
public Executor taskExecutor() {
    ThreadFactory threadFactory = runnable -> {
        Thread thread = new Thread(runnable);
        thread.setDaemon(true);  // 设置为守护线程
        return thread;
    };
    return Executors.newCachedThreadPool(threadFactory);
}

这个配置示例中,我们定义了一个Spring Bean,它是一个线程池,所有的线程都被设置为守护线程。这意味着当应用中没有其他用户线程运行时,应用将退出,这些守护线程也将被终止。

  1. 用户线程
  • 用户线程通常用于执行核心业务逻辑,这类线程不会被自动设置为守护线程。如果在Spring Boot中使用@Async注解或者Spring管理的线程池来执行任务,通常这些线程是用户线程,除非你显式地对其进行配置。


守护线程 vs 用户线程:

  1. 守护线程
  • 守护线程主要用于为其他线程(用户线程)提供服务,如垃圾回收线程。
  • 当所有的用户线程都结束时,JVM会自动退出,并且会终止所有正在运行的守护线程,不管它们是否正在执行。
  • 守护线程通常不用于执行关键业务操作,因为它们可能在任何时候被中断和结束。
  1. 用户线程
  • 用户线程是Java程序的主要执行线程,用于执行程序的主要业务逻辑。
  • JVM会确保所有的用户线程执行完毕才会退出。
  • 即使所有守护线程已经结束,只要有用户线程还在运行,JVM就不会退出。

代码示例

下面是一个Java代码示例,展示如何创建守护线程和用户线程,并观察它们的行为差异。

java复制代码

public class ThreadExample {
    public static void main(String[] args) {
        // 用户线程
        Thread userThread = new Thread(() -> {
            try {
                System.out.println("用户线程正在运行...");
                Thread.sleep(5000); // 模拟执行任务
                System.out.println("用户线程结束。");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        // 守护线程
        Thread daemonThread = new Thread(() -> {
            try {
                while (true) {
                    System.out.println("守护线程正在运行...");
                    Thread.sleep(1000);
                }
            } catch (InterruptedException e) {
                System.out.println("守护线程被中断。");
            } finally {
                System.out.println("守护线程退出。");
            }
        });
        daemonThread.setDaemon(true); // 将此线程设置为守护线程

        userThread.start();
        daemonThread.start();
    }
}

运行解释

在上面的代码中,我们创建了一个用户线程和一个守护线程。用户线程休眠5秒钟后结束,而守护线程在一个无限循环中每秒打印消息。设置线程为守护状态是通过调用 Thread.setDaemon(true) 方法实现的。

  • 当用户线程结束后,即便守护线程的循环还在继续,JVM也会自动退出并终止守护线程的执行。
  • 如果不将线程设置为守护线程,那么它默认是用户线程,JVM会等待它运行结束才会退出。

这个示例很好地展示了守护线程和用户线程在实际应用中的行为差异。

注意事项

  • 资源管理:在使用守护线程时,需要注意它们可能会在任何时候被终止,因此它们不适合执行事务性或需要完成状态维护的重要业务逻辑。
  • 应用退出条件:理解守护线程和用户线程对于应用何时退出的影响非常重要,这可以帮助设计更稳健的多线程应用。

总结来说,虽然Spring Boot本身并不特别区分守护线程与用户线程,但它提供了丰富的工具和框架支持,使得在应用中管理和使用这两种类型的线程变得更加容易和灵活。

相关文章
|
22天前
|
Java Spring
Springboot如何使用线程池
Springboot如何使用线程池
|
2月前
|
Java API 开发者
springboot 多线程的使用原理与实战
在Spring Boot中实现多线程,主要依赖于Spring框架的@Async注解以及底层Java的并发框架。这里将深入剖析Spring Boot多线程的原理,包括@Async注解的工作方式、任务执行器的角色以及如何通过配置来调整线程行为。
44 5
|
4月前
|
存储 设计模式 监控
【JavaEE】多线程案例-线程池
【JavaEE】多线程案例-线程池
|
消息中间件 JavaScript 小程序
SpringBoot 使用线程池如何控制主线程和子线程的事务
SpringBoot 使用线程池如何控制主线程和子线程的事务
|
11月前
|
Java
springboot多线程异步调用
在方法上添加@Async注解,在启动类添加@EnableAsync注解 controller
|
11月前
|
开发框架 监控 Java
SpringBoot多线程极简教程
往往当我们谈论多线程的时候,总会提起一个词“异步”,其实多线程不应该等于异步,异步意味着解耦,虽然多线程本身解耦,但是能实现异步的方式实在太多太多了,如发布/订阅,mq......,所以,一般来说我更倾向于将多线程划归实现异步的一种方式。
643 0
|
前端开发 Java Spring
Java Spring 定时任务配置调试多线程和执行多线程
遇到同一台服务器的定时任务部分执行的情况,暂时找不到原因,估计是因为线程被占满了,有些任务无法执行。 因项目用的是spring mvc的,这里暂时记录spring mvc配置,回头将spring boot的配置详细说明也加上。
235 0
|
Java API
Java开发——35.多线程_(线程的创建及使用)
线程创建方式:1.继承Thread类;2.实现Runnable接口。
Java开发——35.多线程_(线程的创建及使用)
|
安全 Java API
面试官:聊聊java中线程的生命周期
面试官:聊聊java中线程的生命周期
|
Java 调度
Java多线程(3)--线程的生命周期
Java多线程(3)--线程的生命周期
67 0
Java多线程(3)--线程的生命周期