繁体   English   中英

在 CompletableFuture 中返回 autocloseable object 并在 whenComplete 中使用它

[英]Return autocloseable object inside a CompletableFuture and use it in whenComplete

我想在 CompletableFuture 中返回一个可自动关闭的 object 并在 whenComplete 中使用它,而无需稍后手动关闭它。

这是我试过的代码,但当然它不会工作,因为当我返回 Jedis object 时它会自动关闭。我没有任何其他想法。

@Override
    public CompletableFuture<Jedis> execute() {
       if(!isServiceActive()) return CompletableFuture.completedFuture(null);
       return CompletableFuture.supplyAsync(() -> {
           try (Jedis jedis = pool.getResource()) {
              return jedis;
          } catch (RuntimeException e) {
              logger.severe("Impossibile ottenere una nuova risorsa Jedis!", e);
              throw new CompletionException(e);
          }
      }, executor);
  }

一般来说,这是不可能的; CompletableFuture不是为此而设计的。 正如您所指出的,您不能在完成未来之前关闭资源,因为它会在任何消费者开始对其采取行动之前关闭。 这意味着消费者必须负责关闭资源。

但是,如果您的目标是在whenComplete调用中需要那个Jedis实例,那么也许还有另一种解决方案。 修改execute()或创建一个类似于以下内容的新方法:

<T> CompletableFuture<T> execute(Function<? super Jedis, ? extends T> func) {
    if (!isServiceActive()) return CompletableFuture.completedFuture(null);
    return CompletableFuture.supplyAsync(() -> {
        try (Jedis jedis = pool.getResource()) {
            return func.apply(jedis);
        } catch (Exception ex) {
            // log exception
            throw new CompletionException(ex);
        }
    }), executor);
}

Jedis实例在 future 完成时关闭,但它仍然允许您在Function实现中完成所需的工作。 使用它看起来像:

execute(jedis -> {
    // use Jedis instance
    return result;
})
.whenComplete((result, error) -> {
    if (error != null) {
        // process error
    } else {
       // process result
    }
});

虽然我不知道是否可以修改您的代码以使用这种方法,但我注意到您的execute()方法是一个覆盖(我不知道是否来自您控制的类/接口)。 但即使您不能直接修改execute()或提供可行的重载,您仍然可以创建一个实用方法来执行与上述类似的操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM