定时任务Schedule
eg. 每天凌晨1点自动统计昨天的流水(订单数、交易额),每月1号自动统计上月的流水。后台实现定时任务常见的方式有2种
- quartz框架(任务调度)
- springboot的schedule
SpringBoot自带定时任务功能,不需要额外添加依赖
1、引导类上加 @EnableScheduling
2、编写定时任务
@Component //放到spring容器中
public class Xxx {
@Scheduled(fixedRate = 5000) //定时执行,参数指定间隔时间
public void xxx(){
}
}
间隔时间的几种指定方式
@Scheduled(fixedRate = 5000) //每5000ms执行1次。间隔是距离上次执行开始
@Scheduled(fixedDelay = 5000) //上次执行结束,5000ms后再次执行。间隔是距离上次执行结束
// 和以上2种分别对应,只是值写成字符串形式
@Scheduled(fixedRateString = "5000")
@Scheduled(fixedDelayString = "5000")
@Scheduled(cron = "0 0/10 * * * *") //每隔10分钟执行1次
cron有6个字段,依次是
- second
- minute
- hour
- day of month
- month
- day of week
都是 0/x 的形式,表示每隔x时间执行1次,前面不指定的写0,后面不指定的写*
异步任务Async
异步任务可分为2类
扫描二维码关注公众号,回复:
11260340 查看本文章
- 不需要返回结果:处理日志、发送邮件、短信…
- 需要返回结果:比如用户支付订单要校验库存、用户余额、风控…都没有问题才允许支付订单
异步任务都是启动一条新线程来执行,当前线程不阻塞,提高效率。
1、引导类上加 @EnableAsync
2、封装异步任务
@Component //放到spring容器中
@Async //将类中的方法都标识为异步方法。如果不需要标注全部方法,在需要标注的方法上标注@Async即可
public class AsyncTask {
// 不需要返回结果的
public void task1(){
//.....
}
// 需要返回结果的,泛型,可返回任何类型,此处返回String
public Future<String> task2(){
//......
return new AsyncResult<>("ok");
}
public Future<String> task3(){
//......
return new AsyncResult<>("ok");
}
}
3、使用异步任务
@Service
public class XxxService {
@Resource
private AsyncTask asyncTask;
public void xxx(){
//.....
// 执行异步方法时,会启动一条新线程来执行,当前线程不阻塞
asyncTask.task1();
// 需要返回结果的
Future<String> task2 = asyncTask.task2();
Future<String> task3 = asyncTask.task3();
// ...... //当前线程的其它代码
//在当前线程需要使用异步任务的执行结果时,使用while(true)阻塞当前线程,等待异步任务的执行结果
while(true){
if (task2.isDone() && task3.isDone()){ //如果需要的异步任务都执行完了
// 一些操作
try {
if (task2.get().equals("ok") && task3.get().equals("ok")){ //get()获取异步任务返回的值
//....
}
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
//.....
break; //当前线程继续放下执行
}
}
//....
}
}