Igor Kromin |   Consultant. Coder. Blogger. Tinkerer. Gamer.

I've been using the Java Future interface extensively. It's simple to implement and all you need is a ThreadPoolExecutor to run your code in a Thread. There is no messy thread handling, it's all taken care of for you. So what happens if you are running multiple Future tasks and have to wait for all of them to complete before you continue processing their results? Read on to see my approach.

In my particular case I know that all of my Futures return the same kind of data, specifically an Iterator, though it doesn't matter what your Future returns for this to work.

The code goes something like this (example code so all the hardcoded values are dummy values)...
/* used to keep track of running Future instances */
LinkedList<Future> myFutures = new LinkedList<>();
/* start 10 tasks on an executor service and add them to the list of running Futures */
for (int i = 0; i < 10; i++) {
Future myFuture = executorService.submit(new MyFuture(i));
/* get an iterator for the Futures list */
Iterator<Future> futureIter = myFutures.iterator();
/* wait on all Futures to complete processing - 'sync-loop' */
while (futureIter.hasNext()) {
/* all Futures have completed running at this point */

The code sets up a LinkedList to keep track of all of the Future instances that are running. Then 10 Future instances (MyFuture, implementation not shown) are submitted to an executor service to run (not showing creation of this service). After all of that there is a simple loop that uses the Iterator from the LinkedList to loop through all running Future instances, calls get() and then removes that Future instance from the list.

The trick is in the get() call because it blocks the current thread until the Future has completed its task. If that Future has already completed running then get() simply returns the last result. At this point calling remove() on the Iterator takes the Future at the start of the list out of the list which makes it possible to move onto the next Future. Eventually the list will be reduced to zero and the loop will terminate.

After the loop completes, it is guaranteed that all of the Future instances have completed their execution.

In my actual code I do some additional result capture in the while loop. I didn't show that above since that's very implementation specific.


A quick disclaimer...

Although I put in a great effort into researching all the topics I cover, mistakes can happen. Use of any information from my blog posts should be at own risk and I do not hold any liability towards any information misuse or damages caused by following any of my posts.

All content and opinions expressed on this Blog are my own and do not represent the opinions of my employer (Oracle). Use of any information contained in this blog post/article is subject to this disclaimer.
Hi! You can search my blog here ⤵
NOTE: (2022) This Blog is no longer maintained and I will not be answering any emails or comments.

I am now focusing on Atari Gamer.