使用 Spring Boot 多个定时任务阻塞问题的解决方案

简介: 我是小假 期待与你的下一次相遇 ~

为什么Spring Boot 定时任务是单线程的?

想要解释为什么,一定要从源码入手,直接从@EnableScheduling这个注解入手,找到了这个ScheduledTaskRegistrar类,其中有一段代码如下:

  1. protected void scheduleTasks() {
  2.    if (this.taskScheduler == null) {
  3.        this.localExecutor = Executors.newSingleThreadScheduledExecutor();
  4.        this.taskScheduler = new ConcurrentTaskScheduler(this.localExecutor);
  5.    }
  6. }

如果taskScheduler为null,则创建单线程的线程池:Executors.newSingleThreadScheduledExecutor()

多线程定时任务如何配置?

下面介绍三种方案配置多线程下的定时任务。

1、重写SchedulingConfigurer#configureTasks()

直接实现SchedulingConfigurer这个接口,设置taskScheduler,代码如下:

  1. @Configuration
  2. public class ScheduleConfig implements SchedulingConfigurer {
  3.    @Override
  4.    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
  5.        //设定一个长度10的定时任务线程池
  6.        taskRegistrar.setScheduler(Executors.newScheduledThreadPool(10));
  7.    }
  8. }

2、通过配置开启

Spring Boot quartz 已经提供了一个配置用来配置线程池的大小,如下;

  1. spring.task.scheduling.pool.size=10

只需要在配置文件中添加如上的配置即可生效!

3、结合@Async

@Async这个注解都用过,用来开启异步任务的,使用@Async这个注解之前一定是要先配置线程池的,配置如下:

  1. @Bean
  2. public ThreadPoolTaskExecutor taskExecutor() {
  3.    ThreadPoolTaskExecutor poolTaskExecutor = new ThreadPoolTaskExecutor();
  4.    poolTaskExecutor.setCorePoolSize(4);
  5.    poolTaskExecutor.setMaxPoolSize(6);
  6.    // 设置线程活跃时间(秒)
  7.    poolTaskExecutor.setKeepAliveSeconds(120);
  8.    // 设置队列容量
  9.    poolTaskExecutor.setQueueCapacity(40);
  10.    poolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
  11.    // 等待所有任务结束后再关闭线程池
  12.    poolTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
  13.    return poolTaskExecutor;
  14. }

然后在@Scheduled方法上标注@Async这个注解即可实现多线程定时任务,代码如下:

  1. @Async
  2. @Scheduled(cron = "0/2 * * * * ? ")
  3. public void test2() {
  4.    System.out.println("..................执行test2.................");
  5. }


相关文章
|
Java 数据库 Spring
Spring Boot 实现定时任务的动态增删启停
Spring Boot 实现定时任务的动态增删启停
225 0
|
4月前
|
监控 Java BI
《深入理解Spring》定时任务——自动化调度的时间管理者
Spring定时任务通过@Scheduled注解和Cron表达式实现灵活调度,支持固定频率、延迟执行及动态配置,结合线程池与异常处理可提升可靠性,适用于报表生成、健康检查等场景,助力企业级应用自动化。
|
8月前
|
存储 前端开发 Java
|
资源调度 Java 调度
Spring Cloud Alibaba 集成分布式定时任务调度功能
定时任务在企业应用中至关重要,常用于异步数据处理、自动化运维等场景。在单体应用中,利用Java的`java.util.Timer`或Spring的`@Scheduled`即可轻松实现。然而,进入微服务架构后,任务可能因多节点并发执行而重复。Spring Cloud Alibaba为此发布了Scheduling模块,提供轻量级、高可用的分布式定时任务解决方案,支持防重复执行、分片运行等功能,并可通过`spring-cloud-starter-alibaba-schedulerx`快速集成。用户可选择基于阿里云SchedulerX托管服务或采用本地开源方案(如ShedLock)
466 1
|
Java 调度 Spring
Spring之定时任务基本使用篇
本文介绍了在Spring Boot项目中使用定时任务的基本方法。主要通过`@Scheduled`注解实现,需添加`@EnableScheduling`开启定时任务功能。文中详细解析了Cron表达式的语法及常见实例,如每秒、每天特定时间执行等。此外,还探讨了多个定时任务的执行方式(并行或串行)及其潜在问题,并留待后续深入讨论。
617 64
|
资源调度 Java 调度
Spring Cloud Alibaba 集成分布式定时任务调度功能
Spring Cloud Alibaba 发布了 Scheduling 任务调度模块 [#3732]提供了一套开源、轻量级、高可用的定时任务解决方案,帮助您快速开发微服务体系下的分布式定时任务。
16232 110
|
NoSQL Java Redis
Spring Boot 监听 Redis Key 失效事件实现定时任务
Spring Boot 监听 Redis Key 失效事件实现定时任务
407 0
|
Java BI 调度
Java Spring的定时任务的配置和使用
遵循上述步骤,你就可以在Spring应用中轻松地配置和使用定时任务,满足各种定时处理需求。
814 2
|
存储 Java API
简单两步,Spring Boot 写死的定时任务也能动态设置:技术干货分享
【10月更文挑战第4天】在Spring Boot开发中,定时任务通常通过@Scheduled注解来实现,这种方式简单直接,但存在一个显著的限制:任务的执行时间或频率在编译时就已经确定,无法在运行时动态调整。然而,在实际工作中,我们往往需要根据业务需求或外部条件的变化来动态调整定时任务的执行计划。本文将分享一个简单两步的解决方案,让你的Spring Boot应用中的定时任务也能动态设置,从而满足更灵活的业务需求。
1201 4
|
SQL Java 调度
实时计算 Flink版产品使用问题之使用Spring Boot启动Flink处理任务时,使用Spring Boot的@Scheduled注解进行定时任务调度,出现内存占用过高,该怎么办
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。

热门文章

最新文章