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

NOTE: This article is 3 years or older so its information may no longer be relevant. Read on at your own discretion! Comments for this article have automatically been locked, refer to the FAQ for more details.
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.


Skip down to comments...
A quick disclaimer...

Although I put in a great effort into researching all the topics I cover, mistakes can happen. If you spot something out of place, please do let me know.

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.
comments powered by Disqus
Other posts you may like...