SpringBoot 定时任务实践:从入门到多线程解决方案
创作时间:
作者:
@小白创作中心
SpringBoot 定时任务实践:从入门到多线程解决方案
引用
CSDN
1.
https://blog.csdn.net/festone000/article/details/137496081
Q1. SpringBoot怎样创建定时任务?
创建SpringBoot定时任务非常简单,只需在需要执行定时任务的方法上添加@Scheduled注解,并指定cron表达式即可。
@Scheduled(cron = ".....")
Q2. 如上所示创建了定时任务却未能执行是为什么?
如果确认cron表达式没有写错,但定时任务仍然未能执行,可能是由于启动类缺少@EnableScheduling注解。确保在启动类中添加此注解。
Q3. 多个定时任务,未能严格按照指定的时间执行,为什么?
在SpringBoot中,定时任务默认是单线程执行的。如果多个定时任务需要在不同时间点执行,但前一个任务执行时间过长,会导致后续任务延迟执行。
例如,有4个定时任务分别在每天凌晨1点、2点、3点和4点执行。如果第一个任务执行了1.5小时,那么第二个任务将在2点半开始执行,依此类推。
Q4. 如何确保定时任务在特定时间执行?
要确保定时任务在特定时间执行,可以使用多线程。具体步骤如下:
Step 1:初始化线程池
创建一个线程池配置类SchedulerConfig,并实现SchedulingConfigurer接口。
package cn.xxx.starter.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
@Configuration
public class SchedulerConfig implements SchedulingConfigurer {
@Resource
private ThreadPoolTaskScheduler threadPoolTaskScheduler;
@Override
public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
scheduledTaskRegistrar.setTaskScheduler(threadPoolTaskScheduler);
}
}
创建线程池配置类ThreadPoolTaskSchedulerConfig,并配置线程池参数。
package cn.xxx.starter.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
@Configuration
@EnableAsync
public class ThreadPoolTaskSchedulerConfig {
private int corePoolSize = 4;
@Bean
public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
threadPoolTaskScheduler.setPoolSize(corePoolSize);
threadPoolTaskScheduler.setThreadNamePrefix("AsyncJob-thread-");
threadPoolTaskScheduler.setWaitForTasksToCompleteOnShutdown(true);
threadPoolTaskScheduler.setAwaitTerminationSeconds(60 * 60);
threadPoolTaskScheduler.initialize();
return threadPoolTaskScheduler;
}
}
Step 2:启动定时任务时指定使用此线程池
在定时任务类中,使用@Async注解指定使用自定义线程池。
package cn.xxx.starter.task.job;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class Job1 {
@Async(value = "threadPoolTaskScheduler")
@Scheduled(cron = "0 30 */1 * * ?")
public void execute() {
try {
//......
} catch (Exception e) {
log.error("Job1出错 e = {}, stackTrace = {} ", e.getMessage(), JSON.toJSONString(e.getStackTrace()));
} finally {
log.info("Job1结束");
}
}
}
通过以上配置,可以确保多个定时任务在指定时间点并行执行,避免因单线程执行导致的延迟问题。
热门推荐
哪些IT运维考核指标最能反映系统稳定性?
股指期货交割日怎么操作 期货初学者必看
五帝钱的历史与文化意义:从古代货币到现代符号
四川黄龙山五彩池的自然奇观
原生计划1:“斑斓的吃虾者”条纹小鲃
下臂桡神经的解剖结构详解
常见的太阳能电池板发电效率并不高?新材料带来新希望
1MW分布式光伏系统造价详解:从设备到安装的全方位费用指南
MySQL:连接数监控与分类方法探究
【参数化设计与宏应用】:Verilog深入探讨的高级技巧
用户增长运营师是干啥的?人民日报聚焦青岛青年的职业新赛道
做胃肠镜检查前,医生总强调要“无渣饮食”?你吃对了吗?
胃痛能吃中药?中医如何养胃?中医教你3大胃痛防治重点
计数资料,计量资料和等级资料,总结其各有哪些分析方法
TPE手套是食品级的吗?TPE一次性手套可以做食品吗?
家庭必备高性价比家电选购攻略:洗烘、冰箱、电视、油烟机、空调全面解析
后端工程师必修的八大核心技能
清末国人为什么叫“东亚病夫”? 看这些照片就知道了
泰山有多少景色?泰山究竟有多少景色?这份清单超出你的想象!
专科生是大学生吗?听听有关部门的回复
食用穿山甲可能面临哪些法律后果?
“蚩尤”是黄帝给他的贬义称号,他的真实名字,记载在苗族文献中
如何根据员工入职管理指南制定详细的流程?
我国自驾游、旅游产业市场现状,自驾游的发展瓶颈分析
Verilog实现四选一数据选择器
自身抗体及其临床意义,一文全总结清楚
髋关节滑囊炎最佳锻炼方法有什么
布鲁姆的教学目标六个层次
与越南姑娘结婚手续详解:法律全解析及实务操作指南
正月的“正”,什么来头?