`thenRunAsync(...)` 和 `CompletableFuture.runAsync(() -> { ... }); 完全相关吗?
Are `thenRunAsync(...)` and `CompletableFuture.runAsync(() -> { ... });` related at all?
我需要执行一些额外的任务,但让原始线程完成,例如发回 HTTP 响应。
我想我可以做到这一点:
return mainTasksFuture.thenApply(response -> {
CompletableFuture.runAsync(() -> {
// extra tasks
});
return response;
});
但我记得有一个 thenRunAsync
。是
return mainTasksFuture.thenApply(response -> {
return response;
}).thenRunAsync(() -> {
// extra tasks
});
基本上是做同样事情的另一种方法?换句话说,then*Async
方法终止符(完成方法)是 return 前一个链在原始线程中的结果,然后生成一个新线程来执行其余部分吗?
我几乎可以肯定答案是否。对于 CompletableFutures 的新手来说,似乎 可能纯粹基于方法名称。不过,我想要一个确认,以防万一我读到的 ForkJoinPool.commonPool
是 实际上说的是我所怀疑的,只是以不同的方式。
runAsync
和 thenRunAsync
都执行异步 Runnable
任务
executes the given action using this stage's default asynchronous execution facility
问题:换句话说,return前一个链的结果在原始线程中的 then*Async 方法终止符(完成方法),然后生成一个新线程来执行其余的?
答案:不,来自文档一个阶段的执行可能由完成一个阶段,或两个阶段,或两个阶段中的任何一个触发。所以基本上结果可能是 returned 基于程序员如何编码该部分,但现在在你的情况下(使用 thenRunAsync
)结果将是 returned 之后第一阶段完成,因为在第二阶段 thenRunAsync
您将第一阶段的结果作为输入,而不是 returning 任何东西。
One stage's execution may be triggered by completion of a single stage, or both of two stages, or either of two stages. Dependencies on a single stage are arranged using methods with prefix then. Those triggered by completion of both of two stages may combine their results or effects, using correspondingly named methods. Those triggered by either of two stages make no guarantees about which of the results or effects are used for the dependent stage's computation.
第一个例子和第二个例子之间也有细微的差别
示例:1 在此示例中,Runnable
任务在 return 结果之前异步执行,Function
来自 [= runAsync
中的 19=] 和 Runnable
将同时执行
return mainTasksFuture.thenApply(response -> {
CompletableFuture.runAsync(() -> {
// extra tasks
});
return response;
});
示例:2 在此示例中,thenRunAsync
中的 Runnable
任务将在 thenApply
中的 Function
完成后执行
return mainTasksFuture.thenApply(response -> {
return response;
}).thenRunAsync(() -> {
// extra tasks
});
你写了
It just ∗seems* it might be that purely based on method names, to someone new to CompletableFutures.
好吧,方法名称正确地反映了方法的作用。 runAsync
和 thenRunAsync
都启动了 Runnable
和 return 未来的异步执行,这将在异步执行完成时完成。所以名字的相似性是有道理的。
你的代码根本不同。
在此变体中
return mainTasksFuture.thenApply(response -> {
CompletableFuture.runAsync(() -> {
// extra tasks
});
return response;
});
您完全忽略了由 runAsync
编辑的未来 return,因此由 thenApply
编辑的未来 return 将在异步操作完成后立即完成触发。调用者可以在“额外任务”仍然运行并发时检索结果值。
相比之下,与
return mainTasksFuture.thenApply(response -> {
return response;
}).thenRunAsync(() -> {
// extra tasks
});
thenApply
完全过时了,因为它什么都不做。但是您正在 return 由 thenRunAsync
编写的未来 return,它将在 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
编辑的 future return,但与 thenApplyAsync
.
相比,在这种复杂情况下没有任何优势
另一种选择是
return mainTasksFuture.whenComplete((response,failure) -> {
if(failure == null) {
// extra tasks
}
});
因为由 whenComplete
编辑的未来 return 将在完成额外任务后以原始未来的结果完成。但是这个函数总是被评估,即使原来的 future 异常完成,所以如果不需要的话,它需要另一个条件。
我需要执行一些额外的任务,但让原始线程完成,例如发回 HTTP 响应。
我想我可以做到这一点:
return mainTasksFuture.thenApply(response -> {
CompletableFuture.runAsync(() -> {
// extra tasks
});
return response;
});
但我记得有一个 thenRunAsync
。是
return mainTasksFuture.thenApply(response -> {
return response;
}).thenRunAsync(() -> {
// extra tasks
});
基本上是做同样事情的另一种方法?换句话说,then*Async
方法终止符(完成方法)是 return 前一个链在原始线程中的结果,然后生成一个新线程来执行其余部分吗?
我几乎可以肯定答案是否。对于 CompletableFutures 的新手来说,似乎 可能纯粹基于方法名称。不过,我想要一个确认,以防万一我读到的 ForkJoinPool.commonPool
是 实际上说的是我所怀疑的,只是以不同的方式。
runAsync
和 thenRunAsync
都执行异步 Runnable
任务
executes the given action using this stage's default asynchronous execution facility
问题:换句话说,return前一个链的结果在原始线程中的 then*Async 方法终止符(完成方法),然后生成一个新线程来执行其余的?
答案:不,来自文档一个阶段的执行可能由完成一个阶段,或两个阶段,或两个阶段中的任何一个触发。所以基本上结果可能是 returned 基于程序员如何编码该部分,但现在在你的情况下(使用 thenRunAsync
)结果将是 returned 之后第一阶段完成,因为在第二阶段 thenRunAsync
您将第一阶段的结果作为输入,而不是 returning 任何东西。
One stage's execution may be triggered by completion of a single stage, or both of two stages, or either of two stages. Dependencies on a single stage are arranged using methods with prefix then. Those triggered by completion of both of two stages may combine their results or effects, using correspondingly named methods. Those triggered by either of two stages make no guarantees about which of the results or effects are used for the dependent stage's computation.
第一个例子和第二个例子之间也有细微的差别
示例:1 在此示例中,Runnable
任务在 return 结果之前异步执行,Function
来自 [= runAsync
中的 19=] 和 Runnable
将同时执行
return mainTasksFuture.thenApply(response -> {
CompletableFuture.runAsync(() -> {
// extra tasks
});
return response;
});
示例:2 在此示例中,thenRunAsync
中的 Runnable
任务将在 thenApply
中的 Function
完成后执行
return mainTasksFuture.thenApply(response -> {
return response;
}).thenRunAsync(() -> {
// extra tasks
});
你写了
It just ∗seems* it might be that purely based on method names, to someone new to CompletableFutures.
好吧,方法名称正确地反映了方法的作用。 runAsync
和 thenRunAsync
都启动了 Runnable
和 return 未来的异步执行,这将在异步执行完成时完成。所以名字的相似性是有道理的。
你的代码根本不同。
在此变体中
return mainTasksFuture.thenApply(response -> {
CompletableFuture.runAsync(() -> {
// extra tasks
});
return response;
});
您完全忽略了由 runAsync
编辑的未来 return,因此由 thenApply
编辑的未来 return 将在异步操作完成后立即完成触发。调用者可以在“额外任务”仍然运行并发时检索结果值。
相比之下,与
return mainTasksFuture.thenApply(response -> {
return response;
}).thenRunAsync(() -> {
// extra tasks
});
thenApply
完全过时了,因为它什么都不做。但是您正在 return 由 thenRunAsync
编写的未来 return,它将在 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
编辑的 future return,但与 thenApplyAsync
.
另一种选择是
return mainTasksFuture.whenComplete((response,failure) -> {
if(failure == null) {
// extra tasks
}
});
因为由 whenComplete
编辑的未来 return 将在完成额外任务后以原始未来的结果完成。但是这个函数总是被评估,即使原来的 future 异常完成,所以如果不需要的话,它需要另一个条件。