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结束");
}
}
}
通过以上配置,可以确保多个定时任务在指定时间点并行执行,避免因单线程执行导致的延迟问题。
热门推荐
三菜一汤最好吃、最营养的搭配是什么?三菜一汤营养美味全攻略
履约能力定义是怎样的?
4种方法轻松掌握电脑屏幕亮度调节技巧
胰岛素要放冰箱吗?胰岛素保存方式及期限
孩子食物过敏,您是否也有这些疑问?
儿童容易食物过敏,有效识别、紧急对症处理很关键!
叮!~献血者是可以享受优先用血的
无偿献血者的用血权益是否“全国通用”?多地实现异地报销
中药煎煮及服法详细讲解
锈病的产生与防治方法
锈病的产生与防治方法
花生油和玉米油可以混在一起吃吗
【基金E课堂】收益率曲线是什么?长啥样?
西湖游船乘船点全攻略:从画舫到自开船,玩转水上西湖
铝及铝合金锅检测:从材料成分到耐腐蚀性全方位解析
百万医疗险得了癌症还能续保吗?一文详解续保权益与购买建议
脑中风前兆及预防措施
消费市场展现蓬勃活力 低估值消费股名单出炉
阿司匹林肠溶片
肺大疱能自愈吗?医生的专业解答来了
西京学院师生以Vlog创新记录乡村文化 智媒体赋能乡村振兴
房门对上楼梯?四种实用化解方案帮你打造理想居住环境
朱砂的功效与作用:传统应用到现代医学的全面解析
自动化养殖:从手动饲养到智能化饲喂的管理变革
大S与汪小菲:爱如流星划过,从梦幻婚礼到人生新章的转折
用土方法一觉睡到天亮的技巧有哪些?一夜好眠秘诀盘点!
莲花山,佛教与道教共有的圣地,形似莲瓣,中顶平圆,状如莲蕊。
相片回执是什么样子?教你自己拍照片获取
两侧肾疼痛又累是什么问题
物业服务标准等级区别及要求