首页 > 解决方案 > 为什么 CompletableFuture 没有按顺序执行?

问题描述

我的目标是了解 CompletableFuture 是如何工作的。

我的预期结果:如果我这样做了CompletableFuture.runAsync().thenRun().thenRunAsync()。该线程将按顺序执行runAsync() -> thenRun() -> thenRunAsync()

我的实际结果:序列是竞争条件。有时:

  1. runAsync-> thenRunAsync+e-> ...
  2. runAsync-> thenRun-> ...

来自 SO 的参考

public class RunExample5 {
  public static void main(String[] args) {
    ExecutorService e = Executors.newSingleThreadExecutor(r -> new Thread(r, "sole thread"));
    CompletableFuture<?> f = CompletableFuture.runAsync(() -> {
              System.out.println("runAsync:\t" + Thread.currentThread());
              LockSupport.parkNanos((int) 1e9);
            }, e);
    f.thenRun(() -> System.out.println("thenRun:\t" + Thread.currentThread()));
    f.thenRunAsync(() -> System.out.println("thenRunAsync:\t" + Thread.currentThread()));
    f.thenRunAsync(() -> System.out.println("thenRunAsync+e:\t" + Thread.currentThread()),
            e);
    LockSupport.parkNanos((int) 2e9);
    e.shutdown();
  }
}

标签: javacompletable-future

解决方案


你需要

f.thenRun(() -> System.out.println("thenRun:\t" + Thread.currentThread()))
    .thenRunAsync(() -> System.out.println("thenRunAsync:\t" + Thread.currentThread()))
    .thenRunAsync(() -> System.out.println("thenRunAsync+e:\t" + Thread.currentThread()), e);

界面CompletableFuture并不像您想象的那样工作。f它本身不会跟踪对thenRunor的每次调用thenRunAsync并按顺序运行它们;相反,它会在主要工作完成后立即将所有内容视为可运行的thenRunthenRunAsync同时可运行的。如果你想链接更复杂的工作序列,你需要使用thenRunor的返回值thenRunAsync——一个对象——CompletionStage并调用thenRunAsync


推荐阅读