2

我想知道是否存在用于从同步方法调用创建 CompletableFuture 的单线。如果不是,为什么?

长版:

final CompletableFuture<ReturnType> future = new CompletableFuture<>();
final String parameters = "hello";
ReturnType result;
try {
    result = syncMethodCall(parameters);
} catch (Exception e) {
    future.completeExceptionally(e);
}
future.complete(result);
return future;

所需的简短版本(或种类):

final String parameters = "hello";
return CompletableFuture.superMethod(() -> {syncMethodCall(parameters)});
4

2 回答 2

9

由于您接受了执行异步调用的答案,因此不清楚您为什么首先要求“同步方法调用”。执行异步方法调用的任务非常简单CompletableFuture

String parameters="hello";
return CompletableFuture.supplyAsync(() -> syncMethodCall(parameters));

如果您的意图是在返回时强制执行未来已经完成,那么执行起来很容易:

String parameters="hello";
CompletableFuture<ReturnType> f = CompletableFuture.supplyAsync(
                                      () -> syncMethodCall(parameters));
f.handle((x,y) -> null).join();
return f;

之前的handle阶段join确保万一syncMethodCall抛出异常,join不会,因为这似乎是你的意图。但是handle不返回阶段,而是返回记录异常的原始未来。
请注意,使用当前实现在调用者的线程中执行所有操作都有一个技巧:

return CompletableFuture.completedFuture("hello")
    .thenApply(parameters -> syncMethodCall(parameters));

thenApply当未来已经完成时,传递给的函数将立即被评估。但是,抛出的异常仍然syncMethodCall记录在返回的未来中。因此,结果与您问题的“长版”相同。

于 2016-06-20T16:39:06.160 回答
0

由于您希望通过某些方法调用的结果来完成 CompletableFuture,并且您不想自己完成 CompletableFuture - 那么您不需要 CompletableFuture - 任何 Future 实现都可以。例如,

T function(parameters) {
  return new T();
}
T res1 = function(parameters); // sync call
Future<T> f = ForkJoinPool.commonPool.submit(() -> function(parameters));  // async call
T res2 =  f.get();
assert(res1.equals(res2));
于 2016-06-16T16:12:17.837 回答