Springboot 异步执行程序
- 使用注解@EnableAsync开启异步,会自动扫描
- 定义@Component @Async作为组件被容器扫描
示例
入口
@SpringBootApplication
// 扫描所有需要的包,包含一些自用的工具类包所在的路径
@ComponentScan(basePackages = {"com.yxc.imail"})
// 开启异步调用方法
@EnableAsync
public class ImailApplication {
public static void main(String[] args) {
SpringApplication.run(ImailApplication.class, args);
}
}
组件类
@Component
public class AsyncTask {
// 判断任务执行完成,要使用Future
@Async
public Future<Boolean> do1() throws Exception {
long start = System.currentTimeMillis();
Thread.sleep(1000);
long end = System.currentTimeMillis();
System.out.println("Do1 Used: " + (end - start) + " ms");
return new AsyncResult<>(true);
}
@Async
public Future<Boolean> do2() throws Exception {
long start = System.currentTimeMillis();
Thread.sleep(700);
long end = System.currentTimeMillis();
System.out.println("Do2 Used: " + (end - start) + " ms");
return new AsyncResult<>(true);
}
@Async
public Future<Boolean> do3() throws Exception {
long start = System.currentTimeMillis();
Thread.sleep(600);
long end = System.currentTimeMillis();
System.out.println("Do3 Used: " + (end - start) + " ms");
return new AsyncResult<>(true);
}
}
Controller类
@RestController
public class TestController {
@Autowired
private AsyncTask asyncTask;
@GetMapping("/asynctest")
public String asynctest() throws Exception {
long start = System.currentTimeMillis();
Future<Boolean> a = asyncTask.do1();
Future<Boolean> b = asyncTask.do2();
Future<Boolean> c = asyncTask.do3();
while (!a.isDone() || !b.isDone() || !c.isDone()) {
if (a.isDone() && b.isDone() && c.isDone()) {
break;
}
}
long end = System.currentTimeMillis();
String result = "Task Used " + (end - start) + " ms Total";
System.out.println(result);
return result;
}
}
结果
Do3 Used: 601 ms
Do2 Used: 700 ms
Do1 Used: 1000 ms
Task Used 1029 ms Total
使用场景
- 发送短信
- 发送邮件
- 消息推送
使用多线程,线程池,消息队列等都可以实现相同场景