SpringBoot项目如何使用多线程执行定时任务

 更新时间:2025年01月14日 09:34:01   作者:左直拳  
在SpringBoot项目中使用多线程执行定时任务,可以避免一个耗时任务影响其他任务,通过配置线程池任务调度器,Spring会自动使用多线程执行定时任务

SpringBoot使用多线程执行定时任务

我在一个Spring Boot项目中,采用定时器执行一些操作,比如10秒就发送一次数据。

这些操作有2个,如下所示。

我就想,虽然这两个操作各自指定了时间频率,但如果其中一个操作非常耗时,会不会影响其他操作呢?

答案是会。

@Service
public class ShareDataBySend {
    @Autowired
    SendDataService sendDataService;

	//操作1
    @Scheduled(fixedRateString = "${sff.interval}")  // 每 * 秒执行一次
    private void send() {
        sendDataService.sendThem();
    }

	//操作2
    @Scheduled(fixedRateString = "${sff.interval}")  // 每 * 秒执行一次
    private void send2() {
        sendDataService.sendNce();
    }
}

怎么办呢?AI告诉我,引入多线程。

引入多线程

上面代码中,使用了注解@Scheduled。这个注解告诉 Spring ,它需要定期执行标注的方法。@Scheduled依赖于 Spring 的任务调度机制,默认使用一个单线程的任务调度器执行任务。如果没有显式地配置线程池,所有的定时任务都会在同一个线程中按顺序执行。然而,当我们配置一个线程池任务调度器时,Spring 会自动使用这个调度器,这样每个定时任务(如 send() 和 send2())就会在不同的线程中并发执行。

也就是说,我们不需要修改上面这个ShareDataBySend类,而是新注册一个线程池任务调度器,系统就会自动改用多线程。这一切,都源自于Spring Boot框架的本身机制。

代码示例

1、新增线程池任务调度器配置类

import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;

@Configuration
public class SchedulerConfig implements SchedulingConfigurer {
    /**
     * 我们将默认的单线程调度器替换成了 ThreadPoolTaskScheduler,并设置了线程池大小(例如 10)。
     * 这意味着多达 10 个任务可以并发执行。
     */
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
        taskScheduler.setPoolSize(10);  // 设置线程池大小,可根据需要调整
        taskScheduler.initialize();
        taskRegistrar.setTaskScheduler(taskScheduler);
    }
}

在系统启动的时候,Spring Boot会将带有@Config注解的类型实例化到容器中,因此SchedulerConfig 配置的 ThreadPoolTaskScheduler 被初始化。

当定时任务触发时(根据 @Scheduled 的定义),任务被提交给 ThreadPoolTaskScheduler 处理。

如果有多个任务,它们会被分配到线程池中的不同线程上执行,从而实现并发。

2、原ShareDataBySend类

不需要作任何修改

总结

我用java也有好几年了。其实一直都是在用Spring Boot。Spring Boot是一个java开发框架,但我感觉Spring Boot已经足够优秀和方便,对于我来说,Spring Boot == Java。当然了,本质上,Spring Boot可以算是J2EE的一个流派,但青出于蓝。

另外,我就相同的问题,分别问通义千问和chatGPT,前者给出的方案不仅繁琐,而且有错误。这或许不是模型的问题,而是模型训练的材料有问题。也就是说,也许中文世界中,编程问题的答案质量,与老外相比,不在一个档次内。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 在mybatis中使用mapper进行if条件判断

    在mybatis中使用mapper进行if条件判断

    这篇文章主要介绍了在mybatis中使用mapper进行if条件判断,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • 关于解决iReport4.1.1无法正常启动或者闪退或者JDK8不兼容的问题

    关于解决iReport4.1.1无法正常启动或者闪退或者JDK8不兼容的问题

    在安装使用iReport的过程中遇到一个问题,我的iReport始终不能打开,困扰了我好久。接下来通过本文给大家介绍iReport4.1.1无法正常启动或者闪退或者JDK8不兼容的问题,需要的朋友可以参考下
    2018-09-09
  • Java超详细分析讲解哈希表

    Java超详细分析讲解哈希表

    哈希表是一种根据关键码去寻找值的数据映射结构,该结构通过把关键码映射的位置去寻找存放值的地方,说起来可能感觉有点复杂,我想我举个例子你就会明白了,最典型的的例子就是字典
    2022-06-06
  • java打印指定年月的日历

    java打印指定年月的日历

    这篇文章主要为大家详细介绍了Java如何打印指定年月的日历,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-07-07
  • sa-token整合springboot中的代码示例展示

    sa-token整合springboot中的代码示例展示

    sa-token 是一个轻量级的 Java 权限认证框架,它可以很方便地集成到 Spring Boot 项目中,以提供简洁的认证和授权功能,这篇文章主要介绍了sa-token整合springboot中的代码示例展示,需要的朋友可以参考下
    2024-04-04
  • Mybatis拦截器实现数据分表

    Mybatis拦截器实现数据分表

    当数据量比较多时,放在一个表中的时候会影响查询效率,本文主要介绍了Mybatis拦截器实现数据分表,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧
    2024-01-01
  • Java中该如何优雅的使用线程池详解

    Java中该如何优雅的使用线程池详解

    在java开发中我们对“池”的概念并不陌生,常见的有数据库连接池、线程池、对象池、常量池等等,其作用基本上就是避免频繁的创建和回收,造成资源浪费,线程池也不例外,这篇文章主要给大家介绍了关于Java中该如何优雅的使用线程池的相关资料,需要的朋友可以参考下
    2021-12-12
  • 关于springboot打包目录全解析

    关于springboot打包目录全解析

    这篇文章主要介绍了springboot打包目录解析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-07-07
  • MyBatis-Plus多表联查(动态查询)的项目实践

    MyBatis-Plus多表联查(动态查询)的项目实践

    本文主要介绍了MyBatis-Plus多表联查(动态查询)的项目实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-08-08
  • SpringBoot中Aware接口使用及原理解析

    SpringBoot中Aware接口使用及原理解析

    在Spring中存在一个Aware接口,实现该接口可以让我们的Bean获取到Spring容器中特定的资源,但该接口只是个标记接口,不存在任何方法,本文将给大家详细介绍一下SpringBoot中Aware接口使用及原理,需要的朋友可以参考下
    2023-08-08

最新评论