Slim
Slim

Reputation: 1276

Create CompletableFuture from a sync method call

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)});

Upvotes: 5

Views: 19128

Answers (2)

Holger
Holger

Reputation: 298233

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.

Upvotes: 12

Alexei Kaigorodov
Alexei Kaigorodov

Reputation: 13535

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));

Upvotes: 0

Related Questions