分布式调度器之Spring Task 的使用详解
Spring Task是 Spring 框架的一个组件,它为任务调度提供了支持,使开发者能 创建后台任务 或 定期执行任务
1、启动类(App.java)上加@EnableScheduling注解: 开启基于注解的任务调度器
默认情况下,系统会自动启动一个线程,调度执行项目中定义的所有定时任务
这个注解 是SpringBoot内置的 不需要依赖任何的starter包
2、同步定时任务
需要在定时执行的方法上 添加@Scheduled
注解
定时执行的方法不能有参数,并且一般没有返回值
定时任务所在的类要作为 Spring Bean,在类上添加@Component
注解即可,即:定时方法所在的类,要放到IOC容器里面
注意:使用@Scheduled
注解形式的定时任务,默认是单线程来执行项目中所有的定时任务。
即使如果同一时刻有两个定时任务需要执行,那么只能其中一个定时任务完成之后再执行下一个定时任务。
如果项目只有一个定时任务还好。若定时任务增多时,如果一个任务被阻塞,则会导致其他任务无法正常执行。
若要改变这种行为,使得定时任务能够并发执行,可以配置任务调度线程池,来解决以上问题。首先配置一个线程池
package com.***.springtask; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @Component @Slf4j @EnableAsync //开启异步支持 @EnableScheduling //开启定时任务支持 public class ScheduledTask { int i = 1; //@Scheduled(fixedRate = 5000, initialDelay = 15*1000) public void task1(){ // i++; // if(i > 5){ // ThreadUtil.safeSleep(8*1000); // } log.debug("task1执行了{}次,{}",i,Thread.currentThread().getId()); } @Scheduled(cron = "0/5 * * * * ?") @Async("asyncScheduledPool") public void task2(){ // ThreadUtil.safeSleep(8*1000); log.debug("task2执行了,{}",Thread.currentThread().getId()); } }
3、多线程(异步)定时任务
3.1 配置线程池
package com.***.config; import org.springframework.context.annotation.Bean; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Component; import java.util.concurrent.Executor; import java.util.concurrent.ThreadPoolExecutor; @Component public class ExecutorConfig { //定义核心线程数 public static final int CORE_POOL_SIZE = 10; // 最大线程数 public static final int MAX_POOL_SIZE = 20; // 任务队列容量大小 public static final int QUEUE_MAX_COUNT = 100; @Bean("asyncScheduledPool") public Executor asyncScheduledPool(){ //自定义线程池 ThreadPoolTaskExecutor threadPoolExecutor = new ThreadPoolTaskExecutor(); //设置核心线程数 threadPoolExecutor.setCorePoolSize(CORE_POOL_SIZE); //设置最大线程数 : 长工 + 临时工 threadPoolExecutor.setMaxPoolSize(MAX_POOL_SIZE); //设置任务队列容量大小 threadPoolExecutor.setQueueCapacity(QUEUE_MAX_COUNT); //设置线程的名称前缀 threadPoolExecutor.setThreadNamePrefix("myTask-"); //设置拒绝策略 threadPoolExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy()); return threadPoolExecutor; } }
3.2 开启异步支持
要在 Spring Boot 应用中启用异步方法调用,需在启动类上添加 @EnableAsync
注解
3.3 定义异步方法
在服务类中定义一个方法,并使用 @Async
注解标记它以实现异步执行
4、Api说明
4.1 fixedDelay
@Scheduled(fixedDelay = 4000)
4.2 fixedRate
@Scheduled(fixedRate = 10000)
4.3 initialDelay
@Scheduled(initialDelay=1000, fixedRate=5000) //第一次延迟1秒后执行,之后按fixedRate的规则每5秒执行一次
4.4 cron(掌握)
cron表达式 ① 格式
Seconds Minutes Hours Day Month Week
② 特殊符号
*:任意值
-:范围,eg:3-5指3点到5点执行
,:枚举,eg:3,5指3点和5点执行
/:增量,eg:3/5从第3秒开始每隔5秒执行一次
?:忽略,且只能在 日期域 或 星期域 只用
③ 练习 标准格式: * * * * * ?
周一至周五的上午10:15触发
0 15 10 ? * 2-6
表示在每月的1日的凌晨2点调整任务
0 0 2 1 * ?
朝九晚五工作时间内每半小时
0 0/30 9-16 * * ?
每天上午10点,下午2点,4点
0 0 10,14,16 * * ?
表示每个星期三中午12点
0 0 12 ? * 4
在每天下午2点到下午2:59期间的每1分钟触发
0 /1 14-15 * * ?
在每天下午2点到下午2:05期间的每1分钟触发
0 0-5/1 14 * * ?
在每天下午2点到下午2:55期间的每5分钟触发
0 0-55/5 14 * * ?
在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发
0 0-55/5 14,18 * * ?
到此这篇关于分布式调度器之Spring Task 的使用详解的文章就介绍到这了,更多相关Spring Task 使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
Java使用DateTimeFormatter格式化输入的日期时间
这篇文章主要介绍了Java使用DateTimeFormatter格式化输入的日期时间,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2020-01-01SpringBoot Filter修改返回内容,解决请求卡死200的错误
这篇文章主要介绍了SpringBoot Filter修改返回内容,解决请求卡死200的错误问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2023-07-07Security框架:如何使用CorsFilter解决前端跨域请求问题
这篇文章主要介绍了Security框架:如何使用CorsFilter解决前端跨域请求问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2021-11-11一篇文章带你入门Springboot整合微信登录与微信支付(附源码)
微信支付是腾讯公司的支付业务品牌,微信支付商户平台支持线下场所、公众号、小程序、PC网站、APP、企业微信等经营场景快速接入微信支付。这里一篇文章带你入门!2021-06-06
最新评论