-
SpringBoot示例,第5期:3种方式实现定时任务
- 网站名称:SpringBoot示例,第5期:3种方式实现定时任务
- 网站分类:技术文章
- 收录时间:2025-09-04 00:25
- 网站地址:
“SpringBoot示例,第5期:3种方式实现定时任务” 网站介绍
1、基于@Scheduled注解
定时任务类:
package com.xy.schedule;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
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;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.TimeUnit;
@Component
@EnableScheduling
public class ScheduleTask {
// @Scheduled(fixedRate = 5000) // 每隔5秒执行一次
@Scheduled(cron = "0/5 * * * * *") // 每隔5秒执行一次
public void taskA() throws InterruptedException {
LocalDateTime now = LocalDateTime.now();
// 定义时间格式,不包含毫秒
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
// 格式化并打印时间
String formattedTime = now.format(formatter);
System.out.println("taskA当前时间: " + formattedTime);
TimeUnit.SECONDS.sleep(10);
System.out.println("taskA当前时间 end");
}
// @Scheduled(fixedRate = 5000) // 每隔5秒执行一次
@Scheduled(cron = "0/5 * * * * *") // 每隔5秒执行一次
public void taskB() {
LocalDateTime now = LocalDateTime.now();
// 定义时间格式,不包含毫秒
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
// 格式化并打印时间
String formattedTime = now.format(formatter);
System.out.println("taskB当前时间: " + formattedTime);
}
}
这种写法有个缺点,就是几个定时任务在同一个线程呢,任务互相干扰。
也就是说会等其中一个任务执行完了,才会去执行下一个。
修改成:
package com.xy.schedule;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
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;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.TimeUnit;
@Component
@EnableScheduling
@EnableAsync
public class ScheduleTask {
// @Scheduled(fixedRate = 5000) // 每隔5秒执行一次
@Scheduled(cron = "0/5 * * * * *") // 每隔5秒执行一次
@Async
public void taskA() throws InterruptedException {
LocalDateTime now = LocalDateTime.now();
// 定义时间格式,不包含毫秒
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
// 格式化并打印时间
String formattedTime = now.format(formatter);
System.out.println("taskA当前时间: " + formattedTime);
TimeUnit.SECONDS.sleep(10);
System.out.println("taskA当前时间 end");
}
// @Scheduled(fixedRate = 5000) // 每隔5秒执行一次
@Scheduled(cron = "0/5 * * * * *") // 每隔5秒执行一次
@Async
public void taskB() {
LocalDateTime now = LocalDateTime.now();
// 定义时间格式,不包含毫秒
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
// 格式化并打印时间
String formattedTime = now.format(formatter);
System.out.println("taskB当前时间: " + formattedTime);
}
}
基于注解有个不足的地方,无法动态修改cron表达式,只能写死在注解上。
2、基于接口
基于SchedulingConfigurer接口:
package com.xy.schedule;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;
@Component
@EnableScheduling
public class ScheduleTask implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.addTriggerTask(
//添加任务内容
() -> process(),
//设置执行的周期
triggerContext -> {
//查询cron表达式
String cron = "0/5 * * * * *";//这个就可以通过查数据库获取
if (cron.isEmpty()) {
System.out.println("cron is null");
}
return new CronTrigger(cron).nextExecutionTime(triggerContext);
});
}
private void process() {
System.out.println("基于接口的定时任务");
}
}
这种写法就是比较麻烦,每个任务都要新建一个类实现接口。
3、使用Quartz
使用Quartz:首先定义JobDetail(任务详情),然后再定义触发器,就是定义cron表达式。
package com.xy.config;
import org.quartz.CronScheduleBuilder;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class QuartzConfig {
@Bean("helloJob")
public JobDetail helloJobDetail() {
return JobBuilder.newJob(HelloJob.class)
.withIdentity("helloJob")
.usingJobData("msg", "Hello Quartz")
.storeDurably()//即使没有Trigger关联时,也不需要删除该JobDetail
.build();
}
@Bean
public Trigger helloJobTrigger() {
// 每秒执行一次
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0/5 * * * * ?");
return TriggerBuilder.newTrigger()
.forJob(helloJobDetail())
.withIdentity("helloJobTrigger")
.withSchedule(cronScheduleBuilder)
.build();
}
}
新建任务:
package com.xy.config;
import lombok.extern.slf4j.Slf4j;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
import java.util.Date;
@Slf4j
public class HelloJob extends QuartzJobBean {
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
// get parameters
context.getJobDetail().getJobDataMap().forEach(
(k, v) -> log.info("param, key:{}, value:{}", k, v)
);
// your logics
log.info("Hello Job执行时间: " + new Date());
}
}
一个简单的Quartz就完成了,还是比较推荐用Quartz吧
更多相关网站
- JDK8新特性解析:深入比较LocalDateTime和Date之间的区别
- JAVA时间存储类Period和Duration_java中时间
- 3s → 30ms!SpringBoot树形结构“开挂”实录:一次查询提速100倍
- Java 8时间类,越用越香_java时间格式类型
- 实现延迟队列,这些你知道吗?_延迟队列最好方案
- Windows系统安装日期如何修改_win7修改系统安装日期
- SpringBoot扩展——定时任务!_springboot扩展定时任务!怎么解决
- 硬核!最全的延迟任务实现方式汇总!附代码(强烈推荐)
- 解决Snowflake算法时钟回拨的一种方案
- 为什么建议使用 LocalDateTime 而不是 Date
- jdk8Date LocalDateTime类学习笔记
- 侠说java8-LocalDateTime等时间使用手册(全),先mark后看
- LocalDateTime常用方法总结,总有你会用到的
- 最近发表
- 标签列表
-
- mydisktest_v298 (35)
- sql 日期比较 (33)
- document.appendchild (35)
- 头像打包下载 (35)
- 梦幻诛仙表情包 (36)
- java面试宝典2019pdf (26)
- disk++ (30)
- 加密与解密第四版pdf (29)
- iteye (26)
- centos7.4下载 (32)
- intouch2014r2sp1永久授权 (33)
- jdk1.8.0_191下载 (27)
- axure9注册码 (30)
- 兔兔工程量计算软件下载 (27)
- ccproxy破解版 (31)
- aida64模板 (28)
- engine=innodb (33)
- shiro jwt (28)
- segoe ui是什么字体 (27)
- head first java电子版 (32)
- clickhouse中文文档 (28)
- jdk-8u181-linux-x64.tar.gz (32)
- 计算机网络自顶向下pdf (34)
- -dfile.encoding=utf-8 (33)
- jdk1.9下载 (32)