这不是一回事。在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线程中。