如何使用CompletableFuture.thenComposeAsync()? [英] How to use CompletableFuture.thenComposeAsync()?
问题描述
鉴于:
public class Test
{
public static void main(String[] args)
{
int nThreads = 1;
Executor e = Executors.newFixedThreadPool(nThreads);
CompletableFuture.runAsync(() ->
{
System.out.println("Task 1. Thread: " + Thread.currentThread().getId());
}, e).thenComposeAsync((Void unused) ->
{
return CompletableFuture.runAsync(() ->
{
System.out.println("Task 2. Thread: " + Thread.currentThread().getId());
}, e);
}, e).join();
System.out.println("finished");
}
}
我期待单个执行程序线程运行任务1 ,然后是任务2.相反,如果 nThreads
小于2,则代码会挂起。
I am expecting a single executor thread to run task 1, followed by task 2. Instead, the code hangs if nThreads
is less than 2.
- 请解释代码挂起的原因。我可以看到它被阻止在 CompletableFuture:616 等待一些
Future
完成,但目前尚不清楚原因。 - 如果我允许使用2个线程,每个线程用于什么?
- Please explain why the code hangs. I can see it is blocked in CompletableFuture:616 waiting for some
Future
to complete, but it's not clear why. - If I allow the use of 2 threads, what is each thread being used for?
简而言之,请帮助我理解 thenComposeAsync()
实际上有效。 Javadoc看起来像是为机器人而不是人类而写的:)
In short, please help me understand how thenComposeAsync()
actually works. The Javadoc looks like it was written for robots instead of human beings :)
推荐答案
-
thenComposeAsync
方法为执行程序放置一个新任务,该任务抓取单个线程并等待任务2
完成。但是这个没有更多的线程可以运行。您可以改为使用thenCompose
方法,该方法在与任务1
相同的线程中执行,以避免死锁。
The
thenComposeAsync
method places a new task for your executor that grabs the single thread and waits for yourTask 2
to complete. But this one has no more threads to run. You can instead usethenCompose
method that executes in the same thread asTask 1
to avoid the deadlock.
一个线程正在执行任务1
和任务2
和第二个是照顾两者的结果。
One thread is executing Task 1
and Task 2
and the second one is taking care of composing the results of the two.
注意: CompletableFuture
(s)最适合使用 ForkJoinPool
,它可以更有效地处理产生新任务的任务。为此,在Java 8中添加了默认的 ForkJoinPool
,如果没有指定执行程序来运行任务,则默认使用它。
Note: CompletableFuture
(s) work best with a ForkJoinPool
that is more efficient in processing tasks that spawn new tasks. The default ForkJoinPool
was added in Java 8 for this purpose and is used by default if you don't specify an executor to run your tasks.
以下是关于这些新功能在何处发挥作用以及它们如何工作的良好演示:使用Java的反应式编程模式8期货。
Here is a good presentation about where these new features shines and how they work: Reactive Programming Patterns with Java 8 Futures.
这篇关于如何使用CompletableFuture.thenComposeAsync()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!