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...
Hope you found this post useful...

...so please read on! I love writing articles that provide beneficial information, tips and examples to my readers. All information on my blog is provided free of charge and I encourage you to share it as you wish. There is a small favour I ask in return however - engage in comments below, provide feedback, and if you see mistakes let me know.

If you want to show additional support and help me pay for web hosting and domain name registration, donations, no matter how small, are always welcome!

Use of any information contained in this blog post/article is subject to this disclaimer.
comments powered by Disqus
Other posts you may like...