10

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.

1
  • 1
    What you are looking for are indeed promises/futures. Basically, they represent a result that is not available yet. You make all your requests, get back a future for each of them, and then wait on each (or otherwise combine them) to build a result. See also Futures and promises on Wikipedia.
    – Didier L
    Commented Sep 17, 2018 at 16:09

1 Answer 1

8

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:

1
  • 1
    I haven't tried it out, but that sounds exactly what I'm trying to do; thanks for tha!
    – ChrisNY
    Commented Sep 17, 2018 at 23:32

Not the answer you're looking for? Browse other questions tagged or ask your own question.