java—completablefuture的完成顺序

zi8p0yeb  于 2021-07-07  发布在  Java
关注(0)|答案(2)|浏览(481)

我很想了解当一个可完成的未来有多个依赖项时的完成顺序。我本以为依赖项会按添加顺序完成,但事实似乎并非如此。
特别是,这种行为令人惊讶:

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

…导致以下输出。。。

3
2
1
1
2
3
klr1opcd

klr1opcd1#

所以你还没把它们锁起来 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 times ,我打赌至少有一次,你不会看到 3, 2, 1 ,但有些不同。

yzxexxkh

yzxexxkh2#

“x.thenrun()”表达式生成的所有3个子未来都并行运行,因此您不能期望打印数字的任何特定顺序。
“y.thenrun()”也一样。
表达顺序是一个实现特性,将来可能会更改,规范不支持它。

相关问题