问题描述
需要确认一些事情。以下代码:
Need to confirm something. The following code:
CompletableFuture
.supplyAsync(() -> {return doSomethingAndReturnA();})
.thenApply(a -> convertToB(a));
与以下内容相同:
CompletableFuture
.supplyAsync(() -> {
A a = doSomethingAndReturnA();
convertToB(a);
});
对吗?
此外,另外两个问题是我们有什么理由使用 thenApply
?
Furthermore, another two questions following as for "is there any reason why we would use thenApply
?"
1)拥有大量的转换代码?
1) having big code for conversion?
或
2)需要在其他地方重用lambda块吗?
2) need to reuse the lambda block in other places?
推荐答案
不是同一件事。在第二个示例中, thenApply
未使用,可以确定对 convertToB
的调用是在同一个线程中执行的方法 doSomethingAndReturnA
。
It is not the same thing. In the second example where thenApply
is not used it is certain that the call to convertToB
is executed in the same thread as the method doSomethingAndReturnA
.
但是,在使用 thenApply
方法的第一个例子中,可能会发生其他事情。
But, in the first example when the thenApply
method is used other things can happen.
首先,如果执行 doSomethingAndReturnA
的 CompletableFuture
已经完成,在调用程序线程中将调用 thenApply
。如果 CompletableFutures
尚未完成,则函数
传递给 thenApply
将在与 doSomethingAndReturnA
相同的线程中调用。
First of all, if the CompletableFuture
that executes the doSomethingAndReturnA
has completed, the invocation of the thenApply
will happen in the caller thread. If the CompletableFutures
hasn't been completed the Function
passed to thenApply
will be invoked in the same thread as doSomethingAndReturnA
.
令人困惑?那么 (感谢@SotiriosDelimanolis的链接)。
Confusing? Well this article might be helpful (thanks @SotiriosDelimanolis for the link).
我提供了一个简短的例子来说明 thenApply
的工作方式。
I have provided a short example that illustrates how thenApply
works.
public class CompletableTest {
public static void main(String... args) throws ExecutionException, InterruptedException {
final CompletableFuture<Integer> future = CompletableFuture
.supplyAsync(() -> doSomethingAndReturnA())
.thenApply(a -> convertToB(a));
future.get();
}
private static int convertToB(final String a) {
System.out.println("convertToB: " + Thread.currentThread().getName());
return Integer.parseInt(a);
}
private static String doSomethingAndReturnA() {
System.out.println("doSomethingAndReturnA: " + Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "1";
}
}
输出为:
doSomethingAndReturnA: ForkJoinPool.commonPool-worker-1
convertToB: ForkJoinPool.commonPool-worker-1
因此,当第一个操作很慢时(即 CompletableFuture
尚未完成)调用发生在同一个线程中。但是如果我们要从 doSomethingAndReturnA
中删除 Thread.sleep
-call,则输出(可能)就像这样:
So, when the first operation is slow (i.e. the CompletableFuture
is not yet completed) both calls occur in the same thread. But if the we were to remove the Thread.sleep
-call from the doSomethingAndReturnA
the output (may) be like this:
doSomethingAndReturnA: ForkJoinPool.commonPool-worker-1
convertToB: main
请注意 convertToB
来电是在主
thread。
Note that convertToB
call is in the main
thread.
这篇关于CompletableFuture,supplyAsync()和thenApply()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!