我需要执行一些额外的任务,但要让原始线程结束,例如发送回HTTP响应。
我想我可以做到这一点:
return mainTasksFuture.thenApply(response -> {
CompletableFuture.runAsync(() -> {
// extra tasks
});
return response;
});
但是我记得有一个
thenRunAsync
。是return mainTasksFuture.thenApply(response -> {
return response;
}).thenRunAsync(() -> {
// extra tasks
});
基本上是做同一件事的另一种方法?换句话说,
then*Async
方法终止符(完成方法)是否在原始线程中返回前一个链的结果,然后生成一个新线程来执行其余的?我几乎可以肯定,答案是否定的。似乎对于CompletableFutures刚接触的人来说,可能完全基于方法名称。我想得到一个确认,以防万一我读到的关于
ForkJoinPool.commonPool
的内容实际上以不同的方式表达了我的疑问。 最佳答案
你写了
似乎只是纯粹基于方法名称,对于CompletableFutures的新手来说。
好吧,方法名称正确地反映了方法的作用。 runAsync
和thenRunAsync
都启动Runnable
的异步执行并返回Future,该异步完成后将完成。因此,名称的相似性是合理的。
根本上是您的代码不同。
在这个变体中
return mainTasksFuture.thenApply(response -> {
CompletableFuture.runAsync(() -> {
// extra tasks
});
return response;
});
您完全忽略了
runAsync
返回的将来,因此一旦触发了异步操作,就将完成thenApply
返回的将来。当“额外任务”仍在同时运行时,调用方可以检索结果值。与...相比
return mainTasksFuture.thenApply(response -> {
return response;
}).thenRunAsync(() -> {
// extra tasks
});
thenApply
完全已作废,因为它没有任何作用。但是您返回的是thenRunAsync
返回的将来,当Runnable
的异步执行完成并且类型为CompletableFuture<Void>
时,它将完成,因为runnable不会产生值(将来将用null
)。在特殊情况下,除了mainTasksFuture
之外,它都会完成,但在成功情况下,它不会通过结果值。如果第一个变体符合您的实际意图(调用者不应依赖于额外任务的完成),则只需将它们建模为依赖项:
mainTasksFuture.thenRunAsync(() -> {
// extra tasks
});
return mainTasksFuture; // does not depend on the completion of extra task
否则,请使用变体2(减去过时的东西)
return mainTasksFuture.thenRunAsync(() -> {
// extra tasks
}); // depends on the completion of extra task but results in (Void)null
如果您不需要结果值。否则,您可以使用
return mainTasksFuture.thenApplyAsync(response -> {
// extra tasks
return response;
}); // depends on the completion of extra task and returns original result
它与
return mainTasksFuture.thenCompose(response ->
CompletableFuture.runAsync(() -> {
// extra tasks
}).thenApply(_void -> response));
不会忽略
runAsync
返回的未来,但与thenApplyAsync
相比,这种并发症没有任何优势。另一种选择是
return mainTasksFuture.whenComplete((response,failure) -> {
if(failure == null) {
// extra tasks
}
});
因为
whenComplete
返回的未来将在原始任务的结果完成后完成。但是,即使原始的未来特别完成,也总是会评估该功能,因此如果不需要,则需要另一个条件。关于java - `thenRunAsync(...)`和`CompletableFuture.runAsync(()-> {…}))是否完全相关?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57048331/