定时任务:
-
SpringBoot 使用注解定时任务
- 启动类里面@EnableScheduling开启定时任务,自动扫描
- 定时任务业务类 加注解 @组件被容器扫描
- 定期执行的方法加上注解 @Scheduled(fixedRate=2000) 定期执行一次
当需要用到定时任务的时候,首先需要在启动类上加@EnalbeScheduling
@Component
public class ScheduleTask {
@Scheduled(fixedRate = 2000) //定义多久执行一次,单位是毫秒,2000表示2s
//@Scheduled(fixedDelay = 2000) // 执行完之后开始计时
//@Scheduled(cron = "*/1***") // 引号内是linux的crontable表达式
public void mySchedule(){
//TODO 定时任务的内容
}
}
-
cron 定时任务表达式 @Scheduled(cron(cron) */1 * * * * *") 表示姓名="*/1 * * * * *")
- crontab 工具 crontab执行时间计算 - 在线工具
-
fixedRate: 定时执行一次(上一次开始执行时间点后xx秒执行;)
-
fixedDelay: 上一次执行结束时间点后xx秒再次执行
异步任务的实现:
异步任务,相当于开另外一个线程去执行其他的部分,而不需要等这部分执行完再执行其他的部分;
使用场景:适用于处理日志、发送邮件、短信……等
使用步骤:
-
启动类里面使用@EnableAsync注解开启功能,自动扫描
-
定义异步任务类并使用@Component标签组件被扫描,异步方法加上@Async
@Component
@Async // 表示类中的所有方法都是异步方法
public class AsyncTask {
//@Async // 加到方法上面,方法是异步的,加到类上面,类是异步的
public void task1(){
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("test1");
}
public void task2(){
System.out.println("test2");
}
public void task3(){
System.out.println("test3");
}
}
当异步任务需要获取结果的时候:
返回的结果一般用Future<> 来接收
public Future<String> task3(){
System.out.println("test3");
// AsyncResult是用来接收异步任务的结果的,其本身是继承了Future的一个接口
return new AsyncResult<>("my result"); // 具体的返回类型通过泛型来定义的
}
public class AsyncResult<V> implements ListenableFuture<V>
public interface ListenableFuture<T> extends Future<T>
// 通过一系列的包装,但是实际上还是future
调用异步任务
一般会同时定义多个异步任务,实际上相当于这几个异步任务之间并行计算
@Autowired
private AsyncTask asyncTask;
// 下面这三个方法是异步调用的
@GetMapping("async")
public void controllerTest(){
asyncTask.task1();
asyncTask.task2();
Future<String> task3 = asyncTask.task3(); // 接收了异步任务的结果
// 此时还需要从future里面获取结果
for(::){
if(task3.isDone()){ // 判断异步任务是否完成
String result = task3.get(); // 如此才是获取到了异步任务里面返回的字符串
break;
}
}
}
-
注意点:
- 将异步任务封装到类里面,不能直接写到Controller,即单独构建一个AsyncTask类,来写异步任务,然后再controller里面调用这个类,而不能直接把异步任务写入controller
- 增加未来返回结果 AsyncResult("任务执行完成"); Future<> task = new AsyncResult<>();
- 如果需要得到结果需要鉴定所有的task.isDone(),然后通过task.get() 获取里面的内容