Spring Task 定时任务调度

一、概念

Spring Task 是 Spring 框架的一个组件,它为任务调度提供了支持,使得开发者能够创建后台任务或定期执行的任务。通过 Spring Task,您可以方便地在 Java 应用程序中实现定时任务,比如每天凌晨进行数据同步、每小时执行一次清理操作等。

二、使用

1 、配置类启用定时任务支持

启动类(也可以是其他Controller等运行程序的类)添加@EnableScheduling注解,,以开启基于注解的任务调度器,自动扫描 @Scheduled

2、 同步定时任务

创建一个服务类或组件,在其中的方法上使用 @Scheduled 注解来定义定时任务。

复制代码
package com.yy.springtask;

import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class ScheduledTask {

    //上一次开始执行时间和下次开始时间间隔5s
    @Scheduled(fixedRate = 5000)
    public void fixedRateTask() {
        log.debug("fixedRateTask");
    }

    //上次结束到下次开始执行时间间隔5s
    @Scheduled(fixedDelay = 5000)
    public void fixedDelayTask() {
        log.debug("fixedDelayTask");

    }
    //第一次延迟6秒后执行,然后每2s循环执行
   // @Scheduled(initialDelay = 6000,fixedDelay = 2000)
    public void initialDelayTask() throws InterruptedException {
        log.debug("initialDelayTask");
    }

    //使用corn表达式每5s执行一次
   // @Scheduled(cron = "0/5 * * * * ?")
    public void cron() {
        log.debug("cronTask执行");
    }

}

在 Spring Task 中,当我们使用 @Scheduled 注解来定义定时任务时,默认会使用一个单线程的 ScheduledTaskExecutor 来按顺序执行这些任务。这意味着,如果不自定义线程池配置,那么多个定时任务将会按照它们被触发的顺序依次执行,而不是并行执行。

若要改变这种行为,使得定时任务能够并发执行,可以通过配置 ThreadPoolTaskSchedulerThreadPoolTaskExecutor 来创建一个拥有多个工作线程的线程池。这样,不同的定时任务就可以在各自独立的线程中同时运行,提高系统整体的处理效率。

3、异步定时任务

由于定义的定时任务是单线程的,我们可以开启异步定时任务,开启多个任务线程

1.开启异步支持 : 要在 Spring Boot 应用中启用异步方法调用,需在启动类上添加 @EnableAsync 注解。

2.定义异步方法 : 在服务类中定义一个方法,并使用 @Async 注解标记它以实现异步执行:

默认情况下,Spring Boot 会配置一个简单的异步任务执行器。但你可能需要调整其配置,如核心线程数、队列容量、最大线程数等. 例如:

application.properties

复制代码
spring.application.name=xxl_job

#日志配置
logging.level.root=error
logging.level.com.yy = debug

# Spring Task 调度线程池大小,默认为 1,建议根据任务量进行调整。
# 如果不开启异步,可以理解为工厂经理们亲自处理任务
spring.task.scheduling.thread-name-prefix = jingli-
spring.task.scheduling.pool.size = 1
#当开启异步后,@EnableAsync 经理就不再干活了,而是工人干,经理只负责调度,管理

# 配置工人,调度线程名称前缀
spring.task.execution.thread-name-prefix = worker-
# 任务执行线程池配置,核心线程池大小,默认为 8,长工2个
spring.task.execution.pool.core-size= 2
# 最大线程池大小,可以根据实际情况调整,临时工+长工最多为6个
spring.task.execution.pool.max-size= 6
# 线程空闲时间(超时时间),超过这个时间没有任务则关闭线程,单位秒
spring.task.execution.pool.keep-alive= 60s
# 队列容量,用于存放等待执行的任务,如果不指定,int.max
spring.task.execution.pool.queue-capacity= 2
# 拒绝策略,当线程池和队列都满时如何处理新提交的任务,可选值有 AbortPolicy, CallerRunsPolicy 等
spring.task.execution.pool.rejection-policy= CallerRunsPolicy

或者使用yml配置文件

复制代码
# Spring Task 调度线程池大小,默认为 1,建议根据任务量进行调整。
# 如果不开启异步,可以理解为工厂经理们亲自处理任务
spring:
  task:
    scheduling:
      pool:
        size: 10
        # 调度线程名称前缀,默认为 "scheduling-"
        thread-name-prefix: scheduling-

    # 任务执行线程池配置
    execution:
      pool:
        # 核心线程池大小,默认为 8
        core-size: 8
        # 最大线程池大小,可以根据实际情况调整
        max-size: 10
        # 线程空闲时间(超时时间),超过这个时间没有任务则关闭线程,单位秒
        keep-alive: 60s
        # 队列容量,用于存放等待执行的任务,如果不指定,int.max
        queue-capacity: 50
        # 拒绝策略,当线程池和队列都满时如何处理新提交的任务,可选值有 AbortPolicy, CallerRunsPolicy 等
        rejection-policy: CallerRunsPolicy

spring.task.scheduling.pool 和 spring.task.exec

++spring.task.++ ++scheduling++ ++.pool 和 spring.task.++ ++execution++ ++.pool 区别:++

在 Spring Boot 中,spring.task.scheduling.poolspring.task.execution.pool 分别对应着两种不同的线程池配置,分别服务于不同的目的:

spring.task.scheduling.pool : 这个配置是针对 Spring Task 的定时任务调度器 ThreadPoolTaskScheduler。当应用中使用 @Scheduled 注解来定义和执行定时任务时,这个线程池负责调度和执行这些定时任务。配置这个线程池的大小(如 size 属性),意味着你可以控制并发执行定时任务的线程数量,以此来优化系统资源利用,特别是在有多项定时任务需要并行执行时。

spring.task.execution.pool : 这个配置是针对 Spring 异步任务执行器 ThreadPoolTaskExecutor。当应用中使用 @Async 注解来标记某个方法以异步方式执行时,这个线程池会被用来执行那些被异步调用的方法。配置这个线程池的核心线程数(core-size)、最大线程数(max-size)以及线程空闲存活时间(keep-alive)等属性,可以帮助你管理和控制异步任务执行时的并发级别和资源利用率。

总结来说,spring.task.scheduling.pool 主要是用于管理定时任务的并发执行,而 spring.task.execution.pool 则是处理程序中通过异步注解触发的非定时异步任务的并发执行。两者都是为了提高系统处理能力和响应速度,但是应用场景有所不同。

三、 Api说明

1. fixedDelay :上次结束到下次开始执行时间间隔:

复制代码
@Scheduled(fixedDelay = 4000) 

2. fixedRate:上一次开始执行时间和下次开始时间间隔10s(必须开启一步才会按原计划执行)。如:

复制代码
@Scheduled(fixedRate = 10000) 

3. initialDelay:第一次延迟多长时间后再执行。

复制代码
@Scheduled(initialDelay=1000, fixedRate=5000) //第一次延迟1秒后执行,之后按fixedRate的规则每5秒执行一次

4. cron

相关推荐
早已忘记9 小时前
CI相关项
java·前端·ci/cd
砍材农夫10 小时前
使用jstack排查死锁,面试考点
java
小码哥_常16 小时前
Spring Boot 牵手Spring AI,玩转DeepSeek大模型
后端
0xDevNull17 小时前
Java反射机制深度解析:从原理到实战
java·开发语言·后端
华洛17 小时前
我用AI做了一个48秒的真人精品漫剧,不难也不贵
前端·javascript·后端
华科易迅17 小时前
MybatisPlus增删改查操作
android·java·数据库
AugustRed17 小时前
基于现有的 Controller 接口 API 暴露 MCP
spring·mcp
WZTTMoon17 小时前
Spring Boot 中Servlet、Filter、Listener 四种注册方式全解析
spring boot·后端·servlet
standovon17 小时前
Spring Boot整合Redisson的两种方式
java·spring boot·后端
Cosolar18 小时前
LlamaIndex RAG 本地部署+API服务,快速搭建一个知识库检索助手
后端·openai·ai编程