java—completablefuture的完成顺序

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

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

  1. import java.util.concurrent.CompletableFuture;
  2. public class Main {
  3. public static void main(String[] args) {
  4. {
  5. var x = new CompletableFuture<Void>();
  6. x.thenRun(() -> System.out.println(1));
  7. x.thenRun(() -> System.out.println(2));
  8. x.thenRun(() -> System.out.println(3));
  9. x.complete(null);
  10. }
  11. {
  12. var x = new CompletableFuture<Void>();
  13. var y = x.copy();
  14. y.thenRun(() -> System.out.println(1));
  15. y.thenRun(() -> System.out.println(2));
  16. y.thenRun(() -> System.out.println(3));
  17. x.complete(null);
  18. }
  19. }
  20. }

…导致以下输出。。。

  1. 3
  2. 2
  3. 1
  4. 1
  5. 2
  6. 3
klr1opcd

klr1opcd1#

所以你还没把它们锁起来 thenRun ,因此订单上没有担保,但您希望得到一些订单吗?抱歉,事情不是这样的。
文档中没有说明这种情况下的执行顺序,因此无论您现在在输出中看到什么:
不是保证
可以从一个运行到另一个运行(以及从java版本到另一个版本)
用当前设置通过代码证明有点困难,但只需将其更改为:

  1. var x = CompletableFuture.runAsync(() -> {
  2. LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1));
  3. });
  4. x.thenRun(() -> System.out.println(1));
  5. x.thenRun(() -> System.out.println(2));
  6. x.thenRun(() -> System.out.println(3));
  7. x.join();

然后运行这个 20 times ,我打赌至少有一次,你不会看到 3, 2, 1 ,但有些不同。

yzxexxkh

yzxexxkh2#

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

相关问题