实现定时任务的方式有如下几种,本文使用的是每3种
1、常见定时任务 Java自带的java.util.Timer类
timer:配置比较麻烦,时间延后问题
timertask:不推荐
2、Quartz框架
配置更简单
xml或者注解
3、SpringBoot使用注解方式开启定时任务
1)启动类里面 @EnableScheduling开启定时任务,自动扫描
2)定时任务业务类 加注解 @Component被容器扫描
3)定时执行的方法加上注解 @Scheduled(fixedRate=2000) 定期执行一次
@Scheduled注解 参数详细说明
crontab 工具 https://tool.lu/crontab/
1、cron 定时任务表达式 @Scheduled(cron="*/1 * * * * *") 表示每秒
2、fixedRate: 定时多久执行一次(上一次开始执行时间点后xx秒再次执行;)
3、fixedDelay: 上一次执行结束时间点后xx秒再次执行
4、fixedDelayString: 字符串形式,可以通过配置文件指定
定时任务示例代码,调用的代码省略了
import java.util.Date;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class TestTask {
@Scheduled(fixedRateString="2000")//两秒执行一次
//@Scheduled(cron="*/2 * * * * *")
public void sum() throws InterruptedException{
Thread.sleep(4000L);
System.out.println("结束 当前时间:"+new Date());
}
//@Scheduled(cron="*/1 * * * * *")
public void sum2(){
System.out.println("cron 每秒 当前时间:"+new Date());
}
}
异步任务使用的方法
1、启动类里面使用@EnableAsync注解开启功能,自动扫描
2、定义异步任务类并使用@Component标记组件被容器扫描,异步方法加上@Async
注意点:
1)要把异步任务封装到类里面,不能直接写到Controller
2)增加Future<String> 返回结果 AsyncResult<String>("task执行完成");
3)如果需要拿到结果 需要判断全部的 task.isDone()
3、注意,一定要在Controller层调用测试
异步任务示例代码,任务类
import java.util.concurrent.Future;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Component;
@Component
@Async //可放在类上,也可在方法上
public class AsyncTask {
public void task1() throws InterruptedException{
long begin = System.currentTimeMillis();
Thread.sleep(1000L);
long end = System.currentTimeMillis();
System.out.println("任务1耗时="+(end-begin));
}
public void task2() throws InterruptedException{
long begin = System.currentTimeMillis();
Thread.sleep(2000L);
long end = System.currentTimeMillis();
System.out.println("任务2耗时="+(end-begin));
}
public void task3() throws InterruptedException{
long begin = System.currentTimeMillis();
Thread.sleep(3000L);
long end = System.currentTimeMillis();
System.out.println("任务3耗时="+(end-begin));
}
//获取异步结果
public Future<String> task4() throws InterruptedException{
long begin = System.currentTimeMillis();
Thread.sleep(2000L);
long end = System.currentTimeMillis();
System.out.println("任务4耗时="+(end-begin));
return new AsyncResult<String>("任务4");
}
public Future<String> task5() throws InterruptedException{
long begin = System.currentTimeMillis();
Thread.sleep(3000L);
long end = System.currentTimeMillis();
System.out.println("任务5耗时="+(end-begin));
return new AsyncResult<String>("任务5");
}
public Future<String> task6() throws InterruptedException{
long begin = System.currentTimeMillis();
Thread.sleep(1000L);
long end = System.currentTimeMillis();
System.out.println("任务6耗时="+(end-begin));
return new AsyncResult<String>("任务6");
}
}
调用方法测试
import java.util.concurrent.Future;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/v1")
public class UserController {
@Autowired
private AsyncTask task;
@GetMapping("async_task")
public JsonData exeTask() throws InterruptedException{
long begin = System.currentTimeMillis();
//异步任务
// task.task1();
// task.task2();
// task.task3();
//异步任务,有返回结果
Future<String> task4 = task.task4();
Future<String> task5 = task.task5();
Future<String> task6 = task.task6();
//无限循环,效率比while(true)快,因为while(true)每次循环要判断循环条件
for(;;){
if (task4.isDone() && task5.isDone() && task6.isDone()) {
break;
}
}
long end = System.currentTimeMillis();
long total = end-begin;
System.out.println("执行总耗时="+total);
return JsonData.buildSuccess(total);
}
}
运行结果,主任务主线程,运行的总时间,也就 3秒多点