这不是一回事。在thenApply
未使用的第二个示例中,可以确定调用convertToB
是在与方法相同的线程中执行的doSomethingAndReturnA
。
但是,在第一个示例中,当thenApply
使用该方法时,可能会发生其他事情。
首先,如果CompletableFuture
执行 的doSomethingAndReturnA
已经完成,则调用thenApply
将发生在调用者线程中。如果CompletableFutures
尚未完成,则Function
传递的thenApply
将在与doSomethingAndReturnA
.
令人困惑?那么这篇文章可能会有所帮助(感谢@SotiriosDelimanolis 的链接)。
我提供了一个简短的示例来说明如何thenApply
工作。
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
尚未完成)时,两个调用都发生在同一个线程中。但是,如果我们要从输出中删除Thread.sleep
-call doSomethingAndReturnA
(可能)是这样的:
doSomethingAndReturnA: ForkJoinPool.commonPool-worker-1
convertToB: main
请注意,convertToB
调用是在main
线程中。