问题
I would like to know if a one-liner exists for creating a CompletableFuture from a synchron method call. If no, why?
Long version:
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;
Short desired version (or kind):
final String parameters = "hello";
return CompletableFuture.superMethod(() -> {syncMethodCall(parameters)});
回答1:
Since you accepted an answer that performs an asynchronous call, it’s unclear why you asked for a “synchron method call” in the first place. The task of performing an asynchronous method invocation is quite easy with CompletableFuture
:
String parameters="hello";
return CompletableFuture.supplyAsync(() -> syncMethodCall(parameters));
If your intention was to enforce the future to be already completed upon returning, it’s easy to enforce:
String parameters="hello";
CompletableFuture<ReturnType> f = CompletableFuture.supplyAsync(
() -> syncMethodCall(parameters));
f.handle((x,y) -> null).join();
return f;
The handle
stage before the join
ensures that in case syncMethodCall
threw an exception, join
won’t, as that seems to be your intention. But the handle
stage is not returned, instead, the original future with the recorded exception will be returned.
Note that there’s a trick to do everything within the caller’s thread with the current implementation:
return CompletableFuture.completedFuture("hello")
.thenApply(parameters -> syncMethodCall(parameters));
The function passed to thenApply
will be evaluated immediately when the future is already completed. But still, exceptions thrown by syncMethodCall
are recorded in the returned future. So the outcome is identical to the “long version” of your question.
回答2:
Since you want that your CompletableFuture is completed with a result of some method call, and you do not want to complete that CompletableFuture yourself - then you need not CompletableFuture - any Future implementation would be ok. For example,
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));
来源:https://stackoverflow.com/questions/37863100/create-completablefuture-from-a-sync-method-call