一、基于注解@Scheduled
@Configuration //1.主要用于标记配置类,兼备Component的效果。
@EnableScheduling // 2.开启定时任务
public class ScheduledTask {
// 0/5 * * * * ?表示每隔5秒执行一次这个方法
@Scheduled(cron = "0/5 * * * * ?")
public void task1() {
System.out.println("task1执行了..");
}
//在每天凌晨1点,把前一天数据进行数据查询添加
@Scheduled(cron = "0 0 1 * * ?")
public void task2() {
System.out.println("task2执行了..");
}
//每隔5000毫秒执行一次
@Scheduled(fixedDelay = 5000)
public void task1() {
System.out.println("task3执行了..");
}
}
@Scheduled
参数详解
1、cron
该参数接收一个cron表达式
,cron表达式
是一个字符串,字符串以5个空格隔开,分开共6个域,每一个域代表一个含义。秒、分、时、日、月、周。
springboot的@Cheduled
不支持第七个域年
的配置,所以只写6个即可。
cron表达式生成
可通过在线生成工具生成:
2. zone
时区,接收一个java.util.TimeZone#ID
。cron表达式
会基于该时区解析。默认是一个空字符串,即取服务器所在地的时区。比如我们一般使用的时区Asia/Shanghai
。该字段我们一般留空。
3. fixedDelay
每隔多少毫秒执行一次
@Scheduled(fixedDelay = 5000)
4. fixedDelayString
与 3. fixedDelay
意思相同,只是使用字符串的形式。唯一不同的是支持占位符。如:
占位符的使用(配置文件中有配置:time.fixedDelay=5000):
@Scheduled(fixedDelayString = "${time.fixedDelay}")
5. fixedRate
上一次开始执行时间点之后多长时间再执行。如:
Copy@Scheduled(fixedRate = 5000) //上一次开始执行时间点之后5秒再执行
fixedRate 的间隔是两次执行时间的开始点,而 fixedDelay 的间隔是前次任务的结束与下次任务的开始。
6. fixedRateString
与 5. fixedRate
意思相同,只是使用字符串的形式。唯一不同的是支持占位符。
7. initialDelay
第一次延迟多长时间后再执行。如:
Copy@Scheduled(initialDelay=1000, fixedRate=5000) //第一次延迟1秒后执行,之后按fixedRate的规则每5秒执行一次
8. initialDelayString
与initialDelay
意思相同,只是使用字符串的形式。唯一不同的是支持占位符。
二、基于接口@SchedulingConfigurer
优点:方便在实际应用中随时修改定时规则(通过修改数据库中的cron表达式实现)
需导入MySql相关依赖,在本地数据库中创建’cron’,专门存放定时任务的表,然后在yml中添加数据源。
DROP DATABASE IF EXISTS `socks`;
CREATE DATABASE `socks`;
USE `SOCKS`;
DROP TABLE IF EXISTS `cron`;
CREATE TABLE `cron` (
`cron_id` varchar(30) NOT NULL PRIMARY KEY,
`cron` varchar(30) NOT NULL
);
INSERT INTO `cron` VALUES ('1', '0/5 * * * * ?');
@Configuration //1.主要用于标记配置类,兼备Component的效果。
@EnableScheduling // 2.开启定时任务
public class DynamicScheduleTask implements SchedulingConfigurer {
@Mapper
public interface CronMapper {
@Select("select cron from cron limit 1")
public String getCron();
}
@Autowired //注入mapper
@SuppressWarnings("all")
CronMapper cronMapper;
/**
* 执行定时任务.
*/
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.addTriggerTask(
//1.添加任务内容(Runnable)
() -> System.out.println("执行动态定时任务: " + LocalDateTime.now().toLocalTime()),
//2.设置执行周期(Trigger)
triggerContext -> {
//2.1 从数据库获取执行周期
String cron = cronMapper.getCron();
//2.2 合法性校验.
if (StringUtils.isEmpty(cron)) {
// Omitted Code ..
}
//2.3 返回执行周期(Date)
return new CronTrigger(cron).nextExecutionTime(triggerContext);
}
);
}
}
三、多线程定时任务
使用@Async结合注解设定多线程定时任务
//@Component注解用于对那些比较中立的类进行注释;
//相对与在持久层、业务层和控制层分别采用 @Repository、@Service 和 @Controller 对分层中的类进行注释
@Component
@EnableScheduling // 1.开启定时任务
@EnableAsync // 2.开启多线程
public class MultithreadScheduleTask {
@Async
@Scheduled(fixedDelay = 1000) //间隔1秒
public void first() throws InterruptedException {
System.out.println("第一个定时任务开始 : " + LocalDateTime.now().toLocalTime() + "\r\n线程 : " + Thread.currentThread().getName());
System.out.println();
Thread.sleep(1000 * 10);
}
@Async
@Scheduled(fixedDelay = 2000)
public void second() {
System.out.println("第二个定时任务开始 : " + LocalDateTime.now().toLocalTime() + "\r\n线程 : " + Thread.currentThread().getName());
System.out.println();
}
}