问题描述
我想调用 CompletableFuture.supplyAsync()
将阻止任务委托给另一个线程.一旦该任务完成,我希望 CompletableFuture.thenAccept
使用者在调用线程的上下文中运行.
I want to call CompletableFuture.supplyAsync()
to delegate a blocking task to another thread. Once that task completes I would like for the CompletableFuture.thenAccept
consumer to run in the context of the calling thread.
例如:
// Thread 1
CompletableFuture.supplyAsync(() -> {
// Thread 2
return BlockingMethod();
}).thenAccept((
Object r) -> {
// Thread 1
});
以下代码建议 CompletableFuture.thenAccept
在其自己的线程中运行;可能与 CompletableFuture.supplyAsync
相同,因为我在运行它时获得了相同的线程ID:
The following code suggests that CompletableFuture.thenAccept
runs in its own thread; probably the same pool as CompletableFuture.supplyAsync
as I get the same thread ID when I run it:
System.out.println("Sync thread supply " + Thread.currentThread().getId());
CompletableFuture.supplyAsync(() -> {
System.out.println("Async thread " + Thread.currentThread().getId());
try {
Thread.sleep(2000);
}
catch (Exception e) {
e.printStackTrace();
}
return true;
}).thenAccept((
Boolean r) -> {
System.out.println("Sync thread consume " + Thread.currentThread().getId());
});
Thread.sleep(3000);
是否可以使 CompletableFuture.thenAccept
与调用线程同时运行?
Is it possible to have CompletableFuture.thenAccept
run concurrently with the calling thread?
推荐答案
CompletableFuture
仅在以下情况下执行您向 thenAccept
注册的 Consumer
接收者 CompletableFuture
(由 supplyAsync
返回的一个)已完成,因为它需要完成时所用的值.
The CompletableFuture
will only execute the Consumer
you register with thenAccept
when the receiver CompletableFuture
(one returned by supplyAsync
) is completed, since it needs the value it was completed with.
如果在调用 thenAccept
后接收方 CompletableFuture
完成,则 Consumer
将在调用线程中执行.否则,它将在完成提交给 supplyAsync
的 Supplier
的任何线程上执行.
If the receiver CompletableFuture
is complete when thenAccept
is invoked, then the Consumer
will be executed in the calling thread. Otherwise, it will execute on whatever thread completes the Supplier
submitted to supplyAsync
.
这是一个令人困惑的问题,因为线程一次只能运行一件事.一个线程没有当前.当前是一个跨越多个线程的属性.
This is a confusing question because a thread can only run one thing at a time. There's no concurrently for a single thread. Concurrently is a property that spans multiple threads.
如果希望 Consumer
在调用 thenAccept
的同一线程上运行,则在 CompletableFuture
join >,阻塞该线程,直到将来完成.然后,您可以自己执行 Consumer
或调用 thenAccept
来为您执行.
If you want the Consumer
to run on the same thread that invoked thenAccept
, then join
on the CompletableFuture
, blocking this thread until the future is completed. You can then execute the Consumer
yourself or call thenAccept
to execute it for you.
例如
CompletableFuture<Boolean> receiver = CompletableFuture.supplyAsync(() -> {
System.out.println("Async thread " + Thread.currentThread().getId());
try {
Thread.sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
return true;
});
receiver.join();
Consumer<Boolean> consumer = (Boolean r) -> {
System.out.println("Sync thread consume " + Thread.currentThread().getId());
};
consumer.accept(receiver.get());
(省略了异常处理.)
如果希望 Consumer
与提供给 supplyAsync
的 Supplier
并行运行,那是不可能的.该 Consumer
旨在消耗 Supplier
产生的值.在 Supplier
(供应商)完成之前,该值不可用.
If you want the Consumer
to run in parallel with the Supplier
supplied to supplyAsync
, that's not possible. That Consumer
is meant to consume the value produced by the Supplier
. That value isn't available until the Supplier
is finished.
这篇关于从调用线程运行CompletableFuture.thenAccept?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!