简体   繁体   English

CompletableFuture 的完成顺序

[英]Completion order of CompletableFuture

I'm curious to understand the completion order when a CompletableFuture has multiple dependents.当 CompletableFuture 有多个依赖项时,我很想了解完成顺序。 I would have expected the dependents to complete in the order they were added, but that doesn't seem to be the case.我本来希望家属按照他们添加的顺序完成,但情况似乎并非如此。

In particular, this behaviour is surprising:特别是,这种行为令人惊讶:

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

...results in the the following output... ...导致以下 output ...

3
2
1
1
2
3

All 3 child futures generated by 'x.thenRun()' expression run in parallel, so you cannot expect any particular order of printed numbers. 'x.thenRun()' 表达式生成的所有 3 个子期货并行运行,因此您不能期望任何特定的打印数字顺序。

The same for 'y.thenRun()'. 'y.thenRun()' 也是如此。

The expressed order is an implementation feature, can change in the future, and is not supported by the specification.表达的顺序是一种实现特性,将来可能会改变,并且不受规范的支持。

So you have not chained those thenRun , as such there are zero guarantees on the order, but you expect some order?所以你没有链接那些thenRun ,因此对订单有零保证,但你期望一些订单? Sorry, that's not how it works.对不起,这不是它的工作方式。

The documentation does not say anything about order of execution in such cases, so whatever you see now in the output:文档没有说明这种情况下的执行顺序,所以无论您现在在 output 中看到什么:

  • is not a guarantee不是保证
  • can change from run to run (and from java version to version)可以从运行更改为运行(以及从 java 版本到版本)

It is a little bit hard to prove via code with your current set-up, but just change it to:使用当前设置通过代码证明有点困难,但只需将其更改为:

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

And run this let's say 20 times , I bet that at least once, you will not see 3, 2, 1 , but something different.运行这个假设20 times ,我打赌至少一次,你不会看到3, 2, 1 ,而是不同的东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM