Springboot中@Async异步,实现异步结果合并统一返回方式

 更新时间:2023年09月27日 08:55:36   作者:Yang疯狂打码中  
这篇文章主要介绍了Springboot中@Async异步,实现异步结果合并统一返回方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

@Async异步,实现异步结果合并统一返回

本文是为了实现在SpringBoot中使用@Async异步时,将所有异步返回的结果合并。

举例

如果我们想拉取三个数据,每个数据拉取时间是2秒钟,想将结果统一返回给前端,以往我们都是这么做

    @Override
    public SysUser getUserA() throws InterruptedException {
        System.out.println("A线程:"+Thread.currentThread().getId());
        SysUser sysUser = new SysUser();
        sysUser.setUserName("A用户");
        Thread.sleep(2000L);
        System.out.println("A 拉取成功");
        return sysUser;
    }
    @Override
    public SysUser getUserB() throws InterruptedException {
        System.out.println("B线程:"+Thread.currentThread().getId());
        SysUser sysUser = new SysUser();
        sysUser.setUserName("B用户");
        Thread.sleep(2000L);
        System.out.println("B 拉取成功");
        return sysUser;
    }
    @Override
    public SysUser getUserC() throws InterruptedException {
        System.out.println("C线程:"+Thread.currentThread().getId());
        SysUser sysUser = new SysUser();
        sysUser.setUserName("C用户");
        Thread.sleep(2000L);
        System.out.println("C 拉取成功");
        return sysUser;
    }

执行拉取测试

    @Test
    public void testAsync() throws Exception{
        System.out.println(new Date());
        SysUser a = sysUserService.getUserA();
        SysUser b = sysUserService.getUserB();
        SysUser c = sysUserService.getUserC();
        List<SysUser> list = new ArrayList<>(Arrays.asList(a,b,c));
        list.forEach(user->{
            System.out.println(user.getUserName());
        });
        System.out.println(new Date());
    }

结果:共耗时6秒(一个结果2秒)

如果我们有个需求 ,这三个数据一起返回给前端不能超过5秒,这种情形我们就会使用到异步,

问题

但是如果使用异步,主线程不会等待异步线程返回,会直接执行之后代码返回前端(如下图),前端接收到的就是null

解决

如果我们想达到异步的结果统一返回,就需要使用到CompletableFuture

注:使用@Async时,需要@EnableAsync开启异步,调用@Async的方法不能与@Async所在同一个类中

执行测试:等待异步返回,并收集结果,使用.get获取返回值

结果:可以看出每个方法都是异步并行,2秒就即可返回三个合并后的结果

当前执行流程

为什么耗时是2秒:

CompletableFuture.allOf(a,b,c).join();

我们这里 allOf 传递了 三个 异步线程的返回值, 所以看到上图,也就出现了三个等待返回值的坑位 A B C。

可以把这个想象成一辆车,三个位, 必须人满才发车。

那么要等多久呢?

这三个人几乎是同时走向这辆车的,但是无论其他人走多快,因为得整整齐齐,所以耗时取决于这三个坑位,最慢上车的那个人。

如果我把其中一个B线程改为10秒

结果:可以看出B线程拉取的最慢,并且总耗时为10秒

 

注意:

其实,只要你使用到了  返回接收值CompletableFuture ,其实就已经开始触发,并不是一定要用allOf。 

例如:如果我们在使用CompletableFuture时,在异步中途使用到返回值,那么主线程会等待这个异步线程返回

结果:可以看出主线程一直在等待B线程的返回结果,等待10秒后才继续直接线程C

心得:只要调用了get(),主线程就会等待异步线程结果的返回

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java实现简单点餐系统

    Java实现简单点餐系统

    这篇文章主要为大家详细介绍了Java实现简单点餐系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-01-01
  • mybatis如何封装List<String>类型属性

    mybatis如何封装List<String>类型属性

    这篇文章主要介绍了mybatis如何封装List<String>类型属性问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12
  • Java中短路运算符与逻辑运算符示例详解

    Java中短路运算符与逻辑运算符示例详解

    这篇文章主要给大家介绍了关于Java中短路运算符与逻辑运算符的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • java 中RSA的方式实现非对称加密的实例

    java 中RSA的方式实现非对称加密的实例

    这篇文章主要介绍了java 中RSA的方式实现非对称加密的实例的相关资料,这里提供实例帮助大家理解这部分知识,需要的朋友可以参考下
    2017-08-08
  • 用Java代码实现栈数据结构的基本方法归纳

    用Java代码实现栈数据结构的基本方法归纳

    这篇文章主要介绍了用Java代码实现栈数据结构的基本方法归纳,各种算法的实现也是ACM上经常出现的题目,是计算机学习的基本功,需要的朋友可以参考下
    2015-08-08
  • Java实现每日给女友微信发送早安信息

    Java实现每日给女友微信发送早安信息

    这篇文章主要为大家详细介绍了Java如何实现每日给女友微信发送早安等微信信息,文中的示例代码讲解详细,具有一定的借鉴价值,需要的可以了解一下
    2022-12-12
  • Java抓包工具fiddler实现请求转发

    Java抓包工具fiddler实现请求转发

    Fiddler是一个http协议调试代理工具,本文主要介绍了Java抓包工具fiddler实现请求转发,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-04-04
  • Java多线程 CompletionService

    Java多线程 CompletionService

    这篇文章主要介绍了Java多线程 CompletionService,CompletionService用于提交一组Callable任务,其take方法返回已完成的一个Callable任务对应的Future对象,需要的朋友可以参考一下文章详细内容
    2021-10-10
  • springboot利用@Aspect实现日志工具类的详细代码

    springboot利用@Aspect实现日志工具类的详细代码

    这篇文章主要介绍了springboot利用@Aspect实现日志工具类,通过实例代码介绍了导包及在启动类上进行注解自动扫描的方法,需要的朋友可以参考下
    2022-03-03
  • Java反射之通过反射获取一个对象的方法信息(实例代码)

    Java反射之通过反射获取一个对象的方法信息(实例代码)

    下面小编就为大家带来一篇Java反射之通过反射获取一个对象的方法信息(实例代码)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-10-10

最新评论