【问题标题】:How to fail a java.util.concurrent.Future如何使 java.util.concurrent.Future 失败
【发布时间】:2026-01-22 07:50:02
【问题描述】:

在 vertx 生态系统中有大量使用 io.vertx.core.Futurehttps://vertx.io/docs/apidocs/io/vertx/core/Future.html

这里有一个使用 Vertx Future 的例子:

private Future<Void> prepareDatabase() {

  Future<Void> future = Future.future();

  dbClient = JDBCClient.createShared(vertx, new JsonObject(...));

  dbClient.getConnection(ar -> {    

    if (ar.failed()) {
      LOGGER.error("Could not open a database connection", ar.cause());
      future.fail(ar.cause());  // here
      return; 
    } 

    SQLConnection connection = ar.result();   
    connection.execute(SQL_CREATE_PAGES_TABLE, create -> {
        connection.close();   
        if (create.failed()) {
          future.fail(create.cause());  // here
        } else {
          future.complete();  
        }
     });
  });

  return future;
}

我的印象是io.vertx.core.Futurejava.util.concurrent.Future 有关,但似乎没有。如您所见,告诉 Vertx 未来失败的方法是调用它的 fail() 方法。

另一方面,我们有 CompletableFuture,它是 java.util.concurrent.Future 接口的实现: https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html

我在 CompletableFuture 上没有看到失败方法,我只看到“resolve()”。

所以我的猜测是 CompletableFuture 失败的唯一方法是抛出异常?

CompletableFuture<String> f = CompletableFuture.supplyAsync(() -> {
    throw new RuntimeException("fail this future");
    return "This would be the success result";
});

除了抛出错误之外,有没有办法“失败”CompletableFuture? 换句话说,使用 Vertx Future,我们只需调用 f.fail(),但是 CompletableFuture 呢?

【问题讨论】:

  • 有一个completeExceptionally方法,以及相关的obtrudeException
  • yikes 不射击信使,但这些都是一些奇怪的名字,你能举个例子来说明如何使用它们吗?在网上找到好的例子比我想象的要难。
  • Sigh... CompletableFuture 几乎是我想要使用的东西,除了它在很多方面都被破坏了。我记得我第一次看到 API 时看到了“突兀”之类的东西……呃。
  • 是的,vertx Future API 看起来更加健全

标签: java vert.x completable-future


【解决方案1】:

CompletableFuture 鼓励您从supplyAsync() 方法中抛出异常来描述失败。

正如 cmets 中提到的,还有 completeExceptionally() 方法,如果你手头有一个 Future 并且想要失败,可以使用它。

https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html#completeExceptionally-java.lang.Throwable-

从 Java9 开始,还有 CompletableFuture.failedFuture​(Throwable ex) 构造,如果你想返回一个已经失败的未来。

https://docs.oracle.com/javase/9/docs/api/java/util/concurrent/CompletableFuture.html#failedFuture-java.lang.Throwable-

【讨论】: