目录
前言
有时候我们只知道怎么使用,但是有时不起作用却不知道怎么解决。参考锦成同学的一篇文章
失效
本人也是有遇到过,当调用本类方法(@Async注解)是不起作用的。
来看看这个栗子
解决方案
- 在本类中使用了异步是不支持异步的
- 调用者其实是this,是当前对象,不是真正的代理对象
userService
,spring无法截获这个方法调用 所以不在不在本类中去调用,网上的解决方法有applicationContext.getBean(UserService.class)
和AopContext.currentProxy()
返回值
1.异步方法尽量不要有返回值,即返回void
2.返回基础类型会报错
参考这个
就像早上看肥朝大佬在群里讨论的,由于是异步获取为null,你把null赋值给基础类型,肯定会报错的。
本人的demo
@Test
public void a() {
System.out.println("当前线程:" + Thread.currentThread().getName());
System.out.println(contentArticleDataMonitoringService.a().get());
}
@Override
public Long a() {
System.out.println("当前线程:" + Thread.currentThread().getName());
return 0L;
}
在这个注入类头加上@Async,结果输出null。
个人总结
为啥为null呢?上面已经将了由代理类来执行方法,获取不到值。其次是返回类型不是基础类型,又不会报错。
那么! 如果这时我们去使用long reslut=获取刚刚null值就会报NPE
如何获取异步值
@Override
public Future<Long> a() {
System.out.println("当前线程:" + Thread.currentThread().getName());
return new AsyncResult<>(0L);
}
@Test
public void a() {
System.out.println("当前线程:" + Thread.currentThread().getName());
try {
System.out.println(contentArticleDataMonitoringService.a().get());
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
}
运行结果
当前线程:main
当前线程:yatsenglobal-task-executor-1
0
为啥它又能获取到异步值?
在get里面会一直循环判断线程状态等等直到拿到值
总结
- 异步尽量不要有返回值
- 有返回值的话不要是基础类型,不是基础类型也要使用Future去获取异步结果