问题描述
给出这段代码:
public List<String> findPrices(String product){
List<CompletableFuture<String>> priceFutures =
shops.stream()
.map(shop -> CompletableFuture.supplyAsync(
() -> shop.getPrice(product), executor))
.map(future -> future.thenApply(Quote::parse))
.map(future -> future.thenCompose(quote ->
CompletableFuture.supplyAsync(
() -> Discount.applyDiscount(quote), executor
)))
.collect(toList());
return priceFutures.stream()
.map(CompletableFuture::join)
.collect(toList());
}
这部分:
.map(future -> future.thenCompose(quote ->
CompletableFuture.supplyAsync(
() -> Discount.applyDiscount(quote), executor
)))
可以改写为:
.map(future ->
future.thenComposeAsync(quote -> Discount.applyDiscount(quote), executor))
我从一本书的示例中获取了这段代码,并说这两种解决方案是不同的,但是我不明白为什么.
I took this code from an example of a book and says the two solutions are different, but I do not understand why.
推荐答案
让我们考虑一个看起来像这样的函数:
Let's consider a function that looks like this:
public CompletableFuture<String> requestData(String parameters) {
Request request = generateRequest(parameters);
return CompletableFuture.supplyAsync(() -> sendRequest(request));
}
区别在于调用哪个线程generateRequest()
.
The difference will be with respect to which thread generateRequest()
gets called on.
thenCompose
将在与上游任务相同的线程上调用generateRequest()
(如果上游任务已经完成,则调用该线程).
thenCompose
will call generateRequest()
on the same thread as the upstream task (or the calling thread if the upstream task has already completed).
thenComposeAsync
将在提供的执行程序(如果提供)上调用generateRequest()
,否则将在默认的ForkJoinPool
上调用.
thenComposeAsync
will call generateRequest()
on the provided executor if provided, or on the default ForkJoinPool
otherwise.
这篇关于Java8 thenCompose和thenComposeAsync之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!