[英]Returning multiple values with CompletableFuture.supplyAsync
I am writing a program to download historical quotes from a source. 我正在编写一个程序以从源代码下载历史报价。 The source provides files over http for each day which need to be parsed and processed. 源每天通过http提供需要解析和处理的文件。 The program downloads multiple files in parallel using a CompletableFuture
using different stages. 该程序使用CompletableFuture
不同阶段并行下载多个文件。 The first stage is to make a Http call using HttpClient
and get the response. 第一步是使用HttpClient
进行Http调用并获取响应。
The getHttpResponse()
method returns a CloseableHttpResponse
Object. getHttpResponse()
方法返回一个CloseableHttpResponse
对象。 I also want to return a url for which this http request was made. 我还想返回为此http请求发出的URL。 Simplest way is to have a wrapper object having these 2 fields, but i feel it is too much to have a class just to contain these 2 fields. 最简单的方法是让包装对象具有这两个字段,但是我觉得拥有一个仅包含这两个字段的类实在太多了。 Is there a way with CompletableFuture
or Streams that I can achieve this? 使用CompletableFuture
或Streams是否可以实现这一目标?
filesToDownload.stream()
.map(url -> CompletableFuture.supplyAsync(() -> this.getHttpResponse(url), this.executor) )
.map(httpResponseFuture -> httpResponseFuture.thenAccept(t -> processHttpResponse(t)))
.count();
It's not clear why you want to bring in the Stream API at all costs. 目前尚不清楚为什么要不惜一切代价引入Stream API。 Splitting the CompletableFuture
use into two map
operations causes the problem which wouldn't exist otherwise. 将CompletableFuture
用途分为两个map
操作会导致该问题,否则该问题将不存在。 Besides that, using map
for side effects is an abuse of the Stream API. 除此之外,使用map
产生副作用是对Stream API的滥用。 This may break completely in Java 9, if filesToDownload
is a Stream source with a known size (like almost every Collection). 如果filesToDownload
是具有已知大小(类似于几乎每个Collection)的Stream源,则在Java 9中可能会完全中断。 Then, count()
will simply return that known size, without processing the functions of the map
operations… 然后, count()
将简单地返回该已知大小,而无需处理map
操作的功能…
If you want to pass the URL
and the CloseableHttpResponse
to processHttpResponse
, you can do it as easy as: 如果要将URL
和CloseableHttpResponse
给processHttpResponse
,则可以像以下操作一样简单:
filesToDownload.forEach(url ->
CompletableFuture.supplyAsync(() -> this.getHttpResponse(url), this.executor)
.thenAccept( t -> processHttpResponse(t, url))
);
Even, if you use the Stream API to collect results, there is no reason to split the CompletableFuture
into multiple map
operations: 即使使用Stream API收集结果,也没有理由将CompletableFuture
拆分为多个map
操作:
List<…> result = filesToDownload.stream()
.map(url -> CompletableFuture.supplyAsync(() -> this.getHttpResponse(url), this.executor)
.thenApply( t -> processHttpResponse(t, url)) )
.collect(Collectors.toList())
.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList());
Note that this will collect the CompletableFuture
s into a List
before waiting for any result in a second Stream operation. 请注意,在等待第二次Stream操作的任何结果之前,这会将CompletableFuture
收集到List
中。 This is preferable to using a parallel Stream operation as it ensures that all asynchronous operations have been submitted, before starting to wait. 这比使用并行Stream操作更可取,因为它可以确保在开始等待之前已提交所有异步操作。
Using a single Stream pipeline would imply waiting for the completion of the first job before even submitting the second and using a parallel Stream would only reduce that problem instead of solving it. 使用单个Stream管道意味着甚至在提交第二个任务之前也要等待第一个任务的完成,而使用并行Stream只会减少而不是解决该问题。 It would depend on the execution strategy of the Stream implementation (the default Fork/Join pool), which interferes with actual policy of your specified executor. 这将取决于Stream实现的执行策略(默认的Fork / Join池),这会干扰您指定的执行者的实际策略。 Eg, if the specified executor is supposed to use more threads than CPU cores, the Stream would still submit only as much jobs at a time as there are cores — or even less if there are other jobs on the default Fork/Join pool. 例如,如果指定的执行程序使用的线程多于CPU内核,则Stream一次只能提交与内核数量一样多的作业-如果默认的Fork / Join池中还有其他作业,则提交的线程甚至更少。
In contrast, the behavior of the solution above will be entirely controlled by the execution strategy of the specified executor. 相反,以上解决方案的行为将完全由指定执行者的执行策略控制。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.