如果链中的第一个方法是异步的,那么一系列方法调用 (CompletableFuture API) 是否会异步执行?
Will a chain of method calls (CompletableFuture API) execute asynchronously if the first method in a chain is asynchronous?
我正在研究 CompletableFuture API 有一个例子:
CompletableFuture.completedFuture(url)
.thenComposeAsync(this::readPage, executor)
.thenApply(this::getImageURLs)
.thenApply(this::saveFoundImages)
.....
我有一个问题:如果我将 thenComposeAsync(...)
方法作为第一个调用,链中的其他方法是否会在我通过参数传递的 executor
中执行,或者我应该使用 async 调用其他方法以在特定执行程序中获得异步执行?
好的,所以CompletableFuture
中有3种方法。例如:
thenApply()
thenApplyAsync(Function)
(没有执行者)
thenApplyAsync(Function, Executor)
(有执行者)
last表示这个动作会在你传给它的Executor
执行,也是最明显的
second一个表示动作在ForkJoinPool
.
执行
第一个 更有趣。文档使它听起来很简单,通过:
Actions supplied for dependent completions of non-async methods may be performed by the thread that completes the current CompletableFuture, or by any other caller of a completion method
你需要开始将其分成更小的部分。您需要了解的是,有些线程 完成 某个 CompletableFuture
,有些线程 执行 一些操作,还有是链接 某些相关操作的线程。这些可能都是 不同的 线程。这就是一切的开始:
如果相关操作已经链接,将调用 complete
的线程将成为执行此操作的线程。
如果 future 已经完成,则链接操作的线程将执行它。
由于上述步骤没有线性动作,因此几乎不可能确定 thenApply
将在哪个线程中执行,至少 100% 确定。该操作可以在以下任何一个中执行:
- 调用
complete/completeExceptionally
的线程
- 执行
thenApply
链接的线程
- 调用
join/get
的线程
以上任何一种都有可能。如果你真的想要我做了一个相当有趣的,证明了上面的一些事情。
我不是要挑另一个答案,但他提出了一个相当有趣的观点,我在乞讨中也很困惑:
In your example: After .thenComposeAsync
also all the following chained futures will get completed by executor.
我们很容易证明这是不正确的:
CompletableFuture<String> future1 = CompletableFuture.completedFuture("a");
CompletableFuture<String> future2 = future1.thenApplyAsync(x -> "b" + x, Executors.newCachedThreadPool());
LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1));
CompletableFuture<String> future3 = future2.thenApply(x -> {
System.out.println(Thread.currentThread().getName());
return x + "c";
});
future3.join();
如果您 运行 这个,您将看到的是 main
实际上执行 thenApply
,而不是池中的线程。
我正在研究 CompletableFuture API 有一个例子:
CompletableFuture.completedFuture(url)
.thenComposeAsync(this::readPage, executor)
.thenApply(this::getImageURLs)
.thenApply(this::saveFoundImages)
.....
我有一个问题:如果我将 thenComposeAsync(...)
方法作为第一个调用,链中的其他方法是否会在我通过参数传递的 executor
中执行,或者我应该使用 async 调用其他方法以在特定执行程序中获得异步执行?
好的,所以CompletableFuture
中有3种方法。例如:
thenApply()
thenApplyAsync(Function)
(没有执行者)thenApplyAsync(Function, Executor)
(有执行者)
last表示这个动作会在你传给它的Executor
执行,也是最明显的
second一个表示动作在ForkJoinPool
.
第一个 更有趣。文档使它听起来很简单,通过:
Actions supplied for dependent completions of non-async methods may be performed by the thread that completes the current CompletableFuture, or by any other caller of a completion method
你需要开始将其分成更小的部分。您需要了解的是,有些线程 完成 某个 CompletableFuture
,有些线程 执行 一些操作,还有是链接 某些相关操作的线程。这些可能都是 不同的 线程。这就是一切的开始:
如果相关操作已经链接,将调用
complete
的线程将成为执行此操作的线程。如果 future 已经完成,则链接操作的线程将执行它。
由于上述步骤没有线性动作,因此几乎不可能确定 thenApply
将在哪个线程中执行,至少 100% 确定。该操作可以在以下任何一个中执行:
- 调用
complete/completeExceptionally
的线程 - 执行
thenApply
链接的线程
- 调用
join/get
的线程
以上任何一种都有可能。如果你真的想要我做了一个相当有趣的
我不是要挑另一个答案,但他提出了一个相当有趣的观点,我在乞讨中也很困惑:
In your example: After
.thenComposeAsync
also all the following chained futures will get completed by executor.
我们很容易证明这是不正确的:
CompletableFuture<String> future1 = CompletableFuture.completedFuture("a");
CompletableFuture<String> future2 = future1.thenApplyAsync(x -> "b" + x, Executors.newCachedThreadPool());
LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1));
CompletableFuture<String> future3 = future2.thenApply(x -> {
System.out.println(Thread.currentThread().getName());
return x + "c";
});
future3.join();
如果您 运行 这个,您将看到的是 main
实际上执行 thenApply
,而不是池中的线程。