PK创意闹新春,我正在参加「春节创意投稿大赛」,详情请看:春节创意投稿大赛
在工作中定时任务的执行是极其常见的,比如火车票支付时间为30分钟,30分钟后可能就要调用某个接口进行判断是否支付啦,所以说还是有必要了解一下!
我们主要聊聊三种实现方式(基于springboot项目),如下:
cron表达式,最快入门的方式!ScheduledThreadPoolExecutor线程池的方式,第二入门!Quartz轻量级框架,第三入门!
Cron表达式
1、引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2、开启定时任务并编写cron 表达式来设置调用周期
@Component
@EnableScheduling
public class ScheduledPrint {
private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
/*每5s执行一次*/
@Scheduled(cron = "0/5 * * * * ?")
public void task(){
System.out.println("执行时间:" + sdf.format(new Date()) +",执行内容:你真棒!你真的棒!你是真的帮帮的!");
}
}
3、结果展示
4、简单介绍cron表达式
它是由秒 分 时 日 月 星期组成的,推荐一个在线生成cron表达式的网站!用这个网站就行,很简单!
ScheduledThreadPoolExecutor
1、引入自定义配置文件
2、编写定时任务
@Component
// 一般用来引入自定义的配置文件,如果是application.properties可以不写
@PropertySource(value = {"classpath:application.properties"},encoding = "utf-8")
public class ScheduleThreadPoolPrint {
private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@Value("${initialDelay}")
private long initialDelay;
@Value("${period}")
private long period;
// 在服务加载的时候自动调用,并且只调用一次!
@PostConstruct
public void task(){
System.out.println("项目启动时间:" + sdf.format(new Date()));
// 参数为核心线程数
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);
// 参数一:需要执行的任务
// 参数二:项目启动后延迟时间
// 参数三:执行周期
// 参数四:单位
executor.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
System.out.println("执行时间:" + sdf.format(new Date()) +",执行内容:你真棒!你真的棒!你是真的帮帮的!");
}
},initialDelay, period, TimeUnit.SECONDS);
}
}
3、结果展示
Quartz轻量级框架
不要被框架吓到了,引入一个依赖就可以了,很简单的!
1、引入依赖
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.0</version>
</dependency>
2、实现JOB类,编写需要定时的任务
public class ScheduleTask implements Job {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("执行时间:" + sdf.format(new Date()));
}
}
3、调用定时任务
@Component
public class ScheduleTaskService {
@PostConstruct
public void startTask(){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("当前时间:" + sdf.format(new Date()));
Date startTime = new Date();
startTime.setTime(startTime.getTime() + 5000);
Date endTime = new Date();
endTime.setTime(startTime.getTime() + 10000);
try {
// 1: 定义JobDetail,并绑定任务
JobDetail jobDetail = JobBuilder.newJob(ScheduleTask.class).build();
// 2: 定义Trigger触发器,用来触发定时任务
// 方式一:设置开始和结束时间,不设置结束时间默认一直按照调用周期执行
/*Trigger trigger = TriggerBuilder.newTrigger()
.startAt(startTime).endAt(endTime)
// repeatSecondlyForever(5) 周期为5s
// SimpleScheduleBuilder. 有很多方法,可以看看
.withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(5))
.build();*/
// 方式二:固定执行周期
Trigger trigger = TriggerBuilder.newTrigger()
.startNow()
// withRepeatCount(3) 代表执行 3+1 次
.withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(5).withRepeatCount(3))
.build();
// 3: 定义Schedule,并将JobDetail,Trigger绑定
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.scheduleJob(jobDetail, trigger);
scheduler.start();
} catch (SchedulerException e) {
e.printStackTrace();
}
}
}
方式一的结果:
方式二的结果:
其实他还有很多的骚操作的,如果上面没有满足你的需要,请阅读这篇文章《一文搞懂quartz任务调度框架》妥妥的满足你!
总结:
-
Cron表达式,相对来说比较死板!但是上手很快,如果定时任务一般不修改的话,可以用这种方式! -
ScheduledThreadPoolExecutor,可以通过读取配置文件的方式来动态实现,并且比Cron表达式多来延迟时间,相对来说还是比较灵活一点的!上手也相对比较简单! -
Quartz轻量级框架,上手可能稍微有点麻烦,但是非常的灵活,适用于各种奇葩场景!比如设置起止时间,循环几次,固定时间点,或者固定周期等等!
感谢大家的阅读,我是Alson_Code🆒(现在叫CodeMao,因为审核中还没有更改成功!),一个喜欢把简单问题复杂化,把复杂问题简单化的程序猿! ❤