首页 > 解决方案 > 是否可以在创建它的同一线程中运行一个可完成的未来?

问题描述

想知道是否可以在创建它的线程中运行 completablefuture。你可能会问为什么我需要这样做,因为 completablefuture 是用于异步编程的。原因是我有很少的异步任务和一些我想在生成线程中运行的任务,以便我可以使用 allOf 等并保持代码的一致性

标签: javajava-8completable-future

解决方案


当你说你想知道“一个可完成的未来是否可以在创建它的线程中运行”时,你表现出一种错误的心态。ACompletableFuture不运行。ACompletableFuture只是封装了一个值或异常,最多可以设置一次,我们称之为完成

API 提供了许多方法来安排完成尝试,可能是异步的,但您不应该因为决定如何完成它而分心。

异步完成有一些简单的替代方案:

CompletableFuture<String> f = CompletableFuture.completedFuture("hello");

创造一个立即完成的未来。Java 9 增加failedFuture了对创建一个立即异常完成的未来的支持。

您还可以轻松地创建一个将来在同一线程中完成的未来:

CompletableFuture<String> f = new CompletableFuture<>();

// arbitrary actions

f.complete("hello");

您还可以将工厂方法与执行程序一起使用,立即在启动线程中运行操作:

CompletableFuture<String> f
  = CompletableFuture.supplyAsync(() -> "hello", Runnable::run);

或者

CompletableFuture<String> f
  = CompletableFuture.supplyAsync(() -> {
    if(Math.random() > 0.5) throw new IllegalStateException();
    return "hello";
  }, Runnable::run);

展示与调用complete或创建立即完成的未来的区别。

当然,这些可能性可以与其他功能结合使用,例如allOf

CompletableFuture<String> a = new CompletableFuture<>();
CompletableFuture<String> b = new CompletableFuture<>();
CompletableFuture<String> c = new CompletableFuture<>();

CompletableFuture.allOf(a, b, c).whenComplete((__, t) -> {
  if(t != null) System.err.println("failed with "+t);
  else System.out.println("all completed "+a.join()+", "+b.join()+", "+c.join());
});

System.out.println("step 1");
a.complete("foo");
System.out.println("step 2");
b.complete("bar");
System.out.println("step 3");
c.complete("baz");

推荐阅读