springboot中@Async的简单用法
文章目录
开启配置
在配置文件或者入口文件上新增注解: @EnableAsync
即可
@Async的使用
对应需要异步调用的方法上添加@Async
注解即可
无返回值调用
controller代码
java
@RequestMapping("test1")
public String test1() {
System.out.println("controller1调用开始");
testService.test1();
System.out.println("controller1调用结束");
return "success test1";
}
service代码
java
@Async
public void test1() {
System.out.println("service1调用开始");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("service1调用结束");
}
运行结果
controller1调用开始
controller1调用结束
service1调用开始
service1调用结束
可以看到service的已异步调用
带返回值的调用
如果需要执行耗时操作, 又想在结束后执行如发送通知或者保存数据库等方法时, 我们就可以使用带返回值的调用方法
如果需要返回, 则类型需为Future的子类, 最好是返回 CompletableFuture, 里面提供了更多的扩展
controller代码
java
@RequestMapping("test2")
public String test2() {
System.out.println("controller2调用开始");
CompletableFuture<String> stringCompletableFuture = testService.test2();
stringCompletableFuture.whenComplete((s, throwable) -> {
if (throwable != null) {
System.out.println("出现异常: " + throwable.getLocalizedMessage());
return;
}
if (StringUtils.hasText(s)) {
// todo 此处可以进行发通知/写入数据库等操作
System.out.println("service2返回值: " + s);
}
});
System.out.println("controller2调用结束");
return "success test2";
}
service代码
java
@Async
public CompletableFuture<String> test2() {
System.out.println("service2调用开始");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("service2调用结束");
return CompletableFuture.completedFuture("成功执行");
}
运行结果(未生效请重启应用)
controller2调用开始
service2调用开始
controller2调用结束
service2调用结束
service2返回值: 成功执行
可以看到service的在异步调用结束后, 执行了
whenComplete
里面的内容
如果需要在controlle里面同步执行service, 则调用CompletableFuture.get
方法即可
controller代码
java
// service代码不变
@RequestMapping("test3")
public String test3() throws ExecutionException, InterruptedException {
System.out.println("controller3调用开始");
CompletableFuture<String> stringCompletableFuture = testService.test2();
String s = stringCompletableFuture.get();
System.out.println("controller3调用结束, 返回值: " + s);
return "success test3";
}
运行结果
controller3调用开始
service2调用开始
service2调用结束
controller3调用结束, 返回值: 成功执行
可以看到controller已阻塞等待执行结果, 源码注释也可看出
更多功能请参考CompletableFuture接口, 比如同时调用n个@Async接口并任一执行成功后返回(anyOf
)/全部执行成功后返回(allOf
)等