gpt4 book ai didi

java - 推迟 thenApplyAsync 执行

转载 作者:行者123 更新时间:2023-11-29 04:18:28 30 4
gpt4 key购买 nike

我有以下场景。

CompletableFuture<T> result = CompletableFuture.supplyAsync(task, executor);
result.thenRun(() -> {
...
});
// ....
// after some more code, based on some condition I attach the thenApply() to result.

if ( x == 1) {
result.thenApplyAsync(t -> {

return null;
});
}

问题是,如果 CompletableFuture 线程在主线程到达 thenApplyAsync 之前完成执行怎么办? CompletableFuture 结果是否应附加到 thenApply。即是否应在定义 CompletableFuture.supplyAsync() 本身时声明回调?

还有执行顺序是什么? thenRun() 总是在最后执行(在 thenApply() 之后)?

使用这个策略有什么缺点吗?

最佳答案

您似乎遗漏了一个重点。当您链接一个依赖函数时,您不会改变您调用链接方法的 future 。

相反,这些方法中的每一个都返回一个新的完成阶段,表示相关操作。

由于您将两个相关操作附加到 result,它们表示传递给 supplyAsynctask,因此这两个操作之间没有关系.它们可以以任意顺序运行,甚至可以同时在不同线程中运行。

由于您没有将 thenApplyAsync 返回的 future 存储在任何地方,因此其评估结果无论如何都会丢失。假设您的函数返回与 T 相同类型的结果,您可以使用

if(x == 1) {
result = result.thenApplyAsync(t -> {

return null;
});
}

用新的 future 替换可能完成的 future ,新的 future 只有在评估指定函数的结果时才会完成。通过 thenRun 在原始 future 注册的 runnable 仍然不依赖于这个新的 future。请注意,没有执行程序的 thenApplyAsync 将始终使用默认执行程序,而不管使用哪个执行程序来完成其他 future 。

如果你想确保 Runnable 在任何其他阶段之前已经成功执行,你可以使用

CompletableFuture<T> result = CompletableFuture.supplyAsync(task, executor);
CompletableFuture<Void> thenRun = result.thenRun(() -> {
//...
});
result = result.thenCombine(thenRun, (t,v) -> t);

另一种选择是

result = result.whenComplete((value, throwable) -> {
//...
});

但在这里,即使在异常情况下(包括取消),代码也将始终执行。如果您只想在成功的情况下执行代码,则必须检查 throwable 是否为 null


如果要确保可运行对象在两个操作之后运行,最简单的策略是在定义最终完成阶段时将其链接在 if 语句之后:

if(x == 1) {
result = result.thenApplyAsync(t -> {

return null;
});
}
result.thenRun(() -> {
//...
});

如果这不是一个选项,您将需要一个不完整的 future ,您可以根据任一结果完成:

CompletableFuture<T> result = CompletableFuture.supplyAsync(task, executor);

//...

CompletableFuture<T> finalStage = new CompletableFuture<>();
finalStage.thenRun(() -> {
//...
});

// ...

if(x == 1) {
result = result.thenApplyAsync(t -> {

return null;
});
}
result.whenComplete((v,t) -> {
if(t != null) finalStage.completeExceptionally(t); else finalStage.complete(v);
});

finalStage 最初没有定义完成方式,但我们仍然可以链接相关操作。一旦我们知道实际的 future ,我们就可以链接一个处理程序,它将完成我们的 finalStage,无论我们有什么结果。


最后要注意的是,没有…Async 的方法,如thenRun,对评估线程的控制最少。它们可能会在未来完成的任何线程中执行,例如您示例中的 executor 线程之一,但也可能直接在调用 thenRun 的线程中执行,甚至更不直观,在您的原始示例中,runnable 可能会在不相关的 thenApplyAsync 调用期间执行。

关于java - 推迟 thenApplyAsync 执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50735686/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com