[英]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.