举栗个现实问题:
需求:拉取 业务数据不能超过 5秒。
拉取第三方数据 ,分别需要拉取 A业务数据(需要2秒) 、拉取 B业务数据(需要2秒)、拉取 C业务数据(需要2秒) ,最后再一并返回给前端。
问题:超时调用(项目要求每个接口不能超过 5秒 ),这时候就要多线程的使用了。
使用异步处理:
说明:@Async(“参数”) , 其中参数的意思是:指定使用哪一个线程池执行。
测试一下:
运行结果:
执行示意图:
因为异步标记了三个方法,所以看到主线程时间没被受影响,但是同时返回值也拿不到。
虽然耗时接近0秒, 但是返回给前端的数据就是 null了,这个问题该如何解决?
我们开始加入 CompletableFuture 的使用 。
对代码进行改造一下:
运行结果:
执行简图:
为什么耗时是2秒,帮助理解:
CompletableFuture.allOf(a,b,c).join();
我们这里 allOf 传递了 三个 异步线程的返回值, 所以看到上图,也就出现了三个等待返回值的坑位 A B C。
耗时取决于这三个坑位中,最慢的那个。
试一下:
把pullDataA 改为等待8秒
运行结果:耗时 8秒
只要我想要某个异步线程的返回值,我就把这个方法返回接收值CompletableFuture 加入到 allOf 里面去 。
其实,只要使用到了 返回接收值CompletableFuture ,其实就已经开始触发,并不是一定要用allOf。
举例说明:
System.out.println(a.get()+b.get()+c.get());
里面也调用了get() ,也就是也算是使用了。
再举一个小例子:
这种情况,我们使用了 CompletableFuture分别去接收返回值,但是我们后面没去使用操作它们,也没使用allOf , 看下运行结果:
也就是说,这种情况,不会因为 我们使用了 CompletableFuture 而促使让主线程去等待任何异步线程,和主线程没有任何瓜葛。