@Async你用对了吗

目录

前言

失效

解决方案

返回值

本人的demo

个人总结

如何获取异步值

运行结果

总结


前言

有时候我们只知道怎么使用,但是有时不起作用却不知道怎么解决。参考锦成同学的一篇文章

失效

本人也是有遇到过,当调用本类方法(@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里面会一直循环判断线程状态等等直到拿到值

总结

  1. 异步尽量不要有返回值
  2. 有返回值的话不要是基础类型,不是基础类型也要使用Future去获取异步结果
发布了213 篇原创文章 · 获赞 31 · 访问量 19万+

猜你喜欢

转载自blog.csdn.net/weixin_38336658/article/details/100987971