本文章是为了实现在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(),主线程就会等待异步线程结果的返回
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/67230.html