Java 可完成期货的完成顺序
我很想了解当一个可完成的未来有多个依赖项时的完成顺序。我本来希望家属按照他们被添加的顺序完成,但事实似乎并非如此 特别是,这种行为令人惊讶:Java 可完成期货的完成顺序,java,concurrency,completable-future,Java,Concurrency,Completable Future,我很想了解当一个可完成的未来有多个依赖项时的完成顺序。我本来希望家属按照他们被添加的顺序完成,但事实似乎并非如此 特别是,这种行为令人惊讶: import java.util.concurrent.CompletableFuture; public class Main { public static void main(String[] args) { { var x = new CompletableFuture<Void>()
import java.util.concurrent.CompletableFuture;
public class Main {
public static void main(String[] args) {
{
var x = new CompletableFuture<Void>();
x.thenRun(() -> System.out.println(1));
x.thenRun(() -> System.out.println(2));
x.thenRun(() -> System.out.println(3));
x.complete(null);
}
{
var x = new CompletableFuture<Void>();
var y = x.copy();
y.thenRun(() -> System.out.println(1));
y.thenRun(() -> System.out.println(2));
y.thenRun(() -> System.out.println(3));
x.complete(null);
}
}
}
“x.thenRun()”表达式生成的所有3个子未来并行运行,因此您不能期望打印数字的任何特定顺序 “y.thenRun()”也一样 表示的顺序是一种实现功能,将来可能会更改,并且不受规范支持。因此,您没有将这些
链接起来,然后运行
,因此订单上没有任何保证,但您希望获得一些订单?对不起,事情不是这样的
文档没有说明在这种情况下的执行顺序,因此无论您现在在输出中看到什么:
- 这不是保证
- 可以从一个运行更改为另一个运行(以及从java版本更改为另一个版本)
var x = CompletableFuture.runAsync(() -> {
LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1));
});
x.thenRun(() -> System.out.println(1));
x.thenRun(() -> System.out.println(2));
x.thenRun(() -> System.out.println(3));
x.join();
运行20次,我敢打赌至少一次,你不会看到
3,2,1
,但会看到一些不同的东西。表达式不会并行运行。此处没有发生异步调度。内部实现文档的第一行,CompletableFuture可能有相关的完成操作,收集在链接堆栈中。
虽然不在公共规范中,但它以后进先出的顺序执行依赖项。异步调用的执行顺序在此处无关,我只是指同步调用的顺序。@Vaci但是规范没有告诉你任何顺序,所以你不能假设一个。它是一个堆栈
,但这是一个实现细节。
var x = CompletableFuture.runAsync(() -> {
LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1));
});
x.thenRun(() -> System.out.println(1));
x.thenRun(() -> System.out.println(2));
x.thenRun(() -> System.out.println(3));
x.join();