Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you wait for all asynchronous calls to complete in Java?

Conceptually very simple. We have a huge legacy java site that uses NO threading / async. It takes forever to logon because it makes a dozen calls to different microservices, but all synchronously one at a time: each waits for the other to complete before making the next call. However NONE of the API calls depend on the result of any of the others.

But we do need to have all the results and combine them before we proceed. It seemed really obvious that we should be able to make these dozen calls in parallel, but wait for them ALL to complete to use their data IN THE VERY NEXT STEP.

So everything is synchronous before and after the calls. However it would be nice to send them each off on their own in parallel, asynchronously – or just in parallel – then we are only restricted by the single slowest call, not the total sequential times of all the calls.

I read Java 8 has this great new set of operations around CompletableFuture. But I haven't found my use explained anywhere. We don't want the result to be a promise - we're happy to wait until they all complete and then continue. JS has Promise.all(), but even that returns a promise.

All I can think of is to put a little wait look after the async calls are made, and only continue when we get all the results. Which is obviously nuts.

Am I missing something here? Because it seems so obvious to me, but no one else seems to have a problem with it – or else the approach is so simple no-one bothers to ask, and I'm just not getting it.

like image 519
ChrisNY Avatar asked Sep 17 '18 10:09

ChrisNY


People also ask

How do you handle multiple asynchronous calls in Java?

Make some kind of synchronous operation: after main thread executes request, check somehow if onComplete executed (btw, how? with some kind of flag objects?) and if not, do Thread. sleep(1000) , repeat this until response returned, than make another response.

Is there async await in Java?

Electronic Arts brought the async-await feature from . NET to the Java ecosystem through the ea-async library. This library allows writing asynchronous (non-blocking) code sequentially. Therefore, it makes asynchronous programming easier and scales naturally.

How does Java handle asynchronous code?

An Asynchronous call does not block the program from the code execution. When the call returns from the event, the call returns back to the callback function. So in the context of Java, we have to Create a new thread and invoke the callback method inside that thread.


1 Answers

If I understood it right, you want something like this:

ExecutorService executorService = Executors.newFixedThreadPool(4); // TODO: proper number of threads

Future<Integer> future1 = executorService.submit(() -> callService1()); // TODO: proper type and method
Future<String> future2 = executorService.submit(() -> callService2()); // TODO: proper type and method

executorService.shutdown();
executorService.awaitTermination(5, TimeUnit.MINUTES); // TODO: proper timeout

Integer result1 = future1.get(); // TODO: proper type
String result2 = future2.get(); // TODO: proper type

Explanation:

  • above code creates an ExecutorService with 4 threads, to which you can submit all your tasks (i.e. calls to microservices)
  • then you call ExecutorService.shutdown (no more task submissions allowed) and ExecutorService.awaitTermination (wait till all tasks are finished)
  • finally, you call Future.get on all the futures to get the results
    • note that if a task threw an exception during executing, a call to Future.get will throw an ExecutionException that wraps the exception thrown by the task
like image 80
Tomasz Linkowski Avatar answered Sep 29 '22 06:09

Tomasz Linkowski