当我们在调用某些耗时的方法,比如发起第三方调用时而不关心他的返回值,可以采用@Async来实现异步调用。极大的提升程序的响应速度。
在以往的编程方法中我们一般都是开启另一个线程去处理类似的场景,而在Spring 3.x之后则可以使用@Async。
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Async {
String value() default "";
}
可以看到@Async可以修饰在方法和类上。当修饰方法时,该方法则成为异步方法,这些方法在执行的时候将会被独立的线程去执行。
在Spring和Spring Boot中启用@Async
在启动类上添加注解:@EnableAsync
在相应的方法上添加注解:@Async
需要处理返回值
如果在使用了@Async的方法时还需要处理它的返回值,那么需要用到Future
类。
@Async
public Future<String> asyncMethodWithReturnType() {
System.out.println("Execute method asynchronously - "
+ Thread.currentThread().getName());
try {
Thread.sleep(5000);
return new AsyncResult<String>("hello world !!!!");
} catch (InterruptedException e) {
//
}
return null;
}
以上是异步方法,调用该方法时应该以如下方式调用:
public void testAsyncAnnotationForMethodsWithReturnType()
throws InterruptedException, ExecutionException {
System.out.println("Invoking an asynchronous method. "
+ Thread.currentThread().getName());
Future<String> future = asyncAnnotationExample.asyncMethodWithReturnType();
while (true) { ///这里使用了循环判断,等待获取结果信息
if (future.isDone()) { //判断是否执行完毕
System.out.println("Result from asynchronous process - " + future.get());
break;
}
System.out.println("Continue doing something else. ");
Thread.sleep(1000);
}
}
通过while true
来循环判断异步方法是否正常返回,但是这样的代码在正常情况下完全没有必要性,不如直接写成同步调用。
异常处理
在异步方法中,如果出现了异常,对于调用者而言是无法感知的。如果确实需要处理异常,则需要自定义实现AsyncTaskExecutor。
事务处理
如果想要在异步方法中实现事务,则需要把需要事务管理的方法放到异步方法内部,在内部被调用的方法上添加@Transactional。
例如:方法A,使用了@Async/@Transactional来修饰,但是无法达到事务控制的目的。
方法B,使用了@Async修饰,B中调用了C、D,C/D分别使用@Transactional来修饰,可以达到事务控制的目的。
我的博客即将同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=2djokz1ijr38