Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/360.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_Concurrency_Completable Future - Fatal编程技术网

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();