为什么 CompletableFuture 没有按顺序执行?

Why CompletableFuture did not execute in sequence?

我的目标是了解 CompletableFuture 的工作原理。

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

顺序执行

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

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

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

你需要

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 本身不会按顺序跟踪对 thenRunthenRunAsync 和 运行 的每次调用;相反,它会在主要工作完成后立即将 thenRunthenRunAsync 中的所有内容视为同时 运行nable。如果您想链接更复杂的工作序列,您需要使用 thenRunthenRunAsync 的 return 值——一个 CompletionStage 对象——并调用 thenRunAsync.