1)、启动类加注解@EnableScheduling开启定时任务,自动扫描
2)、定时任务业务类加注解@Component被容器扫描
3)、定时执行的方法加注解@Scheduled定期执行一次
@EnableScheduling // 开启定时任务
@SpringBootApplication
public class SpringBootTest2Application {
public static void main(String[] args) {
SpringApplication.run(SpringBootTest2Application.class, args);
}
}
// 定时任务业务类
@Component
public class TestTask {
@Scheduled(fixedRate = 2000) // 两秒执行一次
public void sum() {
System.out.println("当前时间:" + new Date());
}
}
1)、cron定时任务表达式:@Scheduled(cron = “*/1 * * * * *”) 每秒执行一次
crontab工具:https://tool.lu/crontab/
2)、fixedRate:定时多久执行一次
@Component
public class TestTask {
@Scheduled(fixedRate = 2000)
public void sum() {
System.out.println("开始的当前时间:" + new Date());
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("结束的当前时间:" + new Date());
}
}
运行结果:
开始的当前时间:Mon Mar 04 16:39:24 CST 2019
结束的当前时间:Mon Mar 04 16:39:28 CST 2019
开始的当前时间:Mon Mar 04 16:39:28 CST 2019
结束的当前时间:Mon Mar 04 16:39:32 CST 2019
开始的当前时间:Mon Mar 04 16:39:32 CST 2019
使用fixedRate:如果上一个任务未执行完毕,需要等待上一个任务执行完才能执行下一个任务
3)、fixedDelay:上一次执行结束时间点后几秒再次执行
@Component
public class TestTask {
@Scheduled(fixedDelay = 2000)
public void sum() {
System.out.println("开始的当前时间:" + new Date());
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("结束的当前时间:" + new Date());
}
}
运行结果:
开始的当前时间:Mon Mar 04 16:41:04 CST 2019
结束的当前时间:Mon Mar 04 16:41:08 CST 2019
开始的当前时间:Mon Mar 04 16:41:10 CST 2019
结束的当前时间:Mon Mar 04 16:41:14 CST 2019
开始的当前时间:Mon Mar 04 16:41:16 CST 2019
4)、fixedRateString和fixedDelayString:字符串形式,可以通过配置文件指定
1)、启动类加注解@EnableAsync开启异步任务,自动扫描
2)、定义异步任务并使用@Component标记组件被容器扫描,异步方法加上@Async
注意点:
1)要把异步任务封装到类里面,不能直接写到Controller
2)增加Future
返回结果AsyncResult
3)如果需要拿到结果,需要判断全部的task.isDone()
3)、通过注入方式,注入到Controller里面,如果改为同步任务需要把@Async注释掉
4)、异步任务无返回结果
@EnableAsync //开启异步任务
@SpringBootApplication
public class SpringBootTest2Application {
public static void main(String[] args) {
SpringApplication.run(SpringBootTest2Application.class, args);
}
}
// 异步任务业务类
@Component
@Async
public class AsyncTask {
public void task1() throws InterruptedException {
long begin = System.currentTimeMillis();
TimeUnit.SECONDS.sleep(1);
long end = System.currentTimeMillis();
System.out.println("任务1耗时=" + (end - begin));
}
public void task2() throws InterruptedException {
long begin = System.currentTimeMillis();
TimeUnit.SECONDS.sleep(2);
long end = System.currentTimeMillis();
System.out.println("任务2耗时=" + (end - begin));
}
public void task3() throws InterruptedException {
long begin = System.currentTimeMillis();
TimeUnit.SECONDS.sleep(3);
long end = System.currentTimeMillis();
System.out.println("任务3耗时=" + (end - begin));
}
}
测试类:
@RestController
@RequestMapping("/api/v1")
public class UserController {
@Autowired
private AsyncTask asyncTask;
@RequestMapping("async_task")
public String exeTask() throws InterruptedException {
long begin = System.currentTimeMillis();
asyncTask.task1();
asyncTask.task2();
asyncTask.task3();
long end = System.currentTimeMillis();
System.out.println("执行总耗时=" + (end - begin));
return "success";
}
}
运行结果:
执行总耗时=0
任务1耗时=1001
任务2耗时=2000
任务3耗时=3000
5)、异步任务存在返回结果
// 异步任务业务类
@Component
@Async
public class AsyncTask {
public Future<String> task1() throws InterruptedException {
long begin = System.currentTimeMillis();
TimeUnit.SECONDS.sleep(1);
long end = System.currentTimeMillis();
System.out.println("任务1耗时=" + (end - begin));
return new AsyncResult<String>("任务1");
}
public Future<String> task2() throws InterruptedException {
long begin = System.currentTimeMillis();
TimeUnit.SECONDS.sleep(2);
long end = System.currentTimeMillis();
System.out.println("任务2耗时=" + (end - begin));
return new AsyncResult<String>("任务2");
}
public Future<String> task3() throws InterruptedException {
long begin = System.currentTimeMillis();
TimeUnit.SECONDS.sleep(3);
long end = System.currentTimeMillis();
System.out.println("任务3耗时=" + (end - begin));
return new AsyncResult<String>("任务3");
}
}
测试类:
@RestController
@RequestMapping("/api/v1")
public class UserController {
@Autowired
private AsyncTask asyncTask;
@RequestMapping("async_task")
public String exeTask() throws InterruptedException {
long begin = System.currentTimeMillis();
Future<String> task1 = asyncTask.task1();
Future<String> task2 = asyncTask.task2();
Future<String> task3 = asyncTask.task3();
for (;;) {
if (task1.isDone() && task2.isDone() && task3.isDone()) {
break;
}
}
long end = System.currentTimeMillis();
System.out.println("执行总耗时=" + (end - begin));
return "success";
}
}
运行结果:
任务1耗时=1000
任务2耗时=2001
任务3耗时=3001
执行总耗时=3001
6)、去掉@Async改为同步任务
@Component
public class AsyncTask {
public Future<String> task1() throws InterruptedException {
long begin = System.currentTimeMillis();
TimeUnit.SECONDS.sleep(1);
long end = System.currentTimeMillis();
System.out.println("任务1耗时=" + (end - begin));
return new AsyncResult<String>("任务1");
}
public Future<String> task2() throws InterruptedException {
long begin = System.currentTimeMillis();
TimeUnit.SECONDS.sleep(2);
long end = System.currentTimeMillis();
System.out.println("任务2耗时=" + (end - begin));
return new AsyncResult<String>("任务2");
}
public Future<String> task3() throws InterruptedException {
long begin = System.currentTimeMillis();
TimeUnit.SECONDS.sleep(3);
long end = System.currentTimeMillis();
System.out.println("任务3耗时=" + (end - begin));
return new AsyncResult<String>("任务3");
}
}
测试类同上
运行结果:
任务1耗时=1001
任务2耗时=2001
任务3耗时=3000
执行总耗时=6003