Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 推迟应用同步执行_Java_Java 8_Completable Future - Fatal编程技术网

Java 推迟应用同步执行

Java 推迟应用同步执行,java,java-8,completable-future,Java,Java 8,Completable Future,我有下面的场景 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) {

我有下面的场景

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线程在主线程到达ThenApplySync之前完成执行,该怎么办?是否应将完整的未来结果附加到应用中。i、 e是否应在定义CompletableFuture.SupplySync本身时声明回调

还有,执行的顺序是什么?然后运行始终在应用之后执行


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

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

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

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

由于您没有将ApplySync返回的future存储在任何位置,因此其计算结果将丢失。假设您的函数返回与T相同类型的结果,您可以使用

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

        return null;
    });
}
用新的未来替换可能已完成的未来,新的未来仅在指定函数的结果已被评估时完成。通过thenRun在原始future注册的runnable仍然不依赖于此新future。请注意,不带执行器的ApplyAsync将始终使用默认执行器,无论使用哪个执行器来完成另一个未来

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

CompletableFuture<T> result = CompletableFuture.supplyAsync(task, executor);
CompletableFuture<Void> thenRun = result.thenRun(() -> {
    //...
});
result = result.thenCombine(thenRun, (t,v) -> t);
但在这里,即使在包括取消的例外情况下,代码也将始终执行。如果只想在成功的情况下执行代码,则必须检查throwable是否为null

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

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

        return null;
    });
}
result.thenRun(() -> {
    //...
});
如果这不是一个选项,您将需要一个不完整的未来,您可以根据以下任一结果完成:

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);
});
最后阶段最初没有定义的完成方式,但我们仍然可以链接相关的操作。一旦我们知道了实际的未来,我们就可以链上一个处理程序,它将以我们得到的任何结果完成我们的最后阶段


最后,不带…Async的方法(如thenRun)对计算线程的控制最少。它们可能会在将来完成的任何线程中执行,就像您的示例中的一个executor线程,但也会直接在调用thenRun的线程中执行,更不直观的是,在您的原始示例中,runnable可能会在不相关的ThenApplySync调用中执行。

谢谢。是否有任何方法确保在应用同步之后执行Run或RunAySNC?我知道在这种情况下,它们可以并行运行。我只想在异步运行之后在运行中设置某些值。谢谢。isDone在第一个completionstage之后或在所有依赖项完成之后返回true?@ulab它取决于调用isDone的未来。如果您有依赖链,请使用最后一个,即运行返回的依赖链,以确定整个操作是否已完成。否则,请始终记住,您有一组单独的CompletableFuture实例,每个实例都有自己的完成状态。这正是我想要的!
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);
});