# Executing tasks in parallel using Java Future - codecentric AG Blog

: 7

10/14/11

Recently I was attending a really interesting presentation by Adam Bien who was using Future as part of his demo application. *Future* offers a very elegant way to implement parallel execution of tasks in Java. As I found the concept quite interesting I thought I give it a try in some pure sample class. And as I did so I thought I could as well write a short blog post at the same time, so here we go.

This is technical stuff, so let’s start with the sample class right away:

import java.util.ArrayList; package de.codecentric.blog.sample; import java.util.ArrayList; import java.util.Calendar; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.FutureTask; public class FutureTaskDemo { /** * Maximum amount of numbers to check */ public static final int MAX_NUMBER = 2000000000; /** * Returns the amount of numbers that can be divided by the divisor without remainder. * @param first First number to check * @param last Last number to check * @param divisor Divisor * @return Amount of numbers that can be divided by the divisor without remainder */ public static int amountOfDivisibleBy(int first, int last, int divisor) { int amount = 0; for (int i = first; i <= last; i++) { if (i % divisor == 0) { amount++; } } return amount; } /** * Returns the amount of numbers that can be divided by the divisor without remainder (using parallel execution). * @param first First number to check * @param last Last number to check * @param divisor Divisor * @return Amount of numbers that can be divided by the divisor without remainder * @throws InterruptedException * @throws ExecutionException */ public static int amountOfDivisibleByFuture(final int first, final int last, final int divisor) throws InterruptedException, ExecutionException { int amount = 0; // Prepare to execute and store the Futures int threadNum = 2; ExecutorService executor = Executors.newFixedThreadPool(threadNum); List<FutureTask<Integer>> taskList = new ArrayList<FutureTask<Integer>>(); // Start thread for the first half of the numbers FutureTask<Integer> futureTask_1 = new FutureTask<Integer>(new Callable<Integer>() { @Override public Integer call() { return FutureTaskDemo.amountOfDivisibleBy(first, last / 2, divisor); } }); taskList.add(futureTask_1); executor.execute(futureTask_1); // Start thread for the second half of the numbers FutureTask<Integer> futureTask_2 = new FutureTask<Integer>(new Callable<Integer>() { @Override public Integer call() { return FutureTaskDemo.amountOfDivisibleBy(last / 2 + 1, last, divisor); } }); taskList.add(futureTask_2); executor.execute(futureTask_2); // Wait until all results are available and combine them at the same time for (int j = 0; j < threadNum; j++) { FutureTask<Integer> futureTask = taskList.get(j); amount += futureTask.get(); } executor.shutdown(); return amount; } /** * Executing the example. * @param args Command line arguments * @throws ExecutionException * @throws InterruptedException */ public static void main(String[] args) throws InterruptedException, ExecutionException { // Sequential execution long timeStart = Calendar.getInstance().getTimeInMillis(); int result = FutureTaskDemo.amountOfDivisibleBy(0, MAX_NUMBER, 3); long timeEnd = Calendar.getInstance().getTimeInMillis(); long timeNeeded = timeEnd - timeStart; System.out.println("Result : " + result + " calculated in " + timeNeeded + " ms"); // Parallel execution long timeStartFuture = Calendar.getInstance().getTimeInMillis(); int resultFuture = FutureTaskDemo.amountOfDivisibleByFuture(0, MAX_NUMBER, 3); long timeEndFuture = Calendar.getInstance().getTimeInMillis(); long timeNeededFuture = timeEndFuture - timeStartFuture; System.out.println("Result (Future): " + resultFuture + " calculated in " + timeNeededFuture + " ms"); } } |

import java.util.ArrayList; package de.codecentric.blog.sample; import java.util.ArrayList; import java.util.Calendar; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.FutureTask; public class FutureTaskDemo { /** * Maximum amount of numbers to check */ public static final int MAX_NUMBER = 2000000000; /** * Returns the amount of numbers that can be divided by the divisor without remainder. * @param first First number to check * @param last Last number to check * @param divisor Divisor * @return Amount of numbers that can be divided by the divisor without remainder */ public static int amountOfDivisibleBy(int first, int last, int divisor) { int amount = 0; for (int i = first; i <= last; i++) { if (i % divisor == 0) { amount++; } } return amount; } /** * Returns the amount of numbers that can be divided by the divisor without remainder (using parallel execution). * @param first First number to check * @param last Last number to check * @param divisor Divisor * @return Amount of numbers that can be divided by the divisor without remainder * @throws InterruptedException * @throws ExecutionException */ public static int amountOfDivisibleByFuture(final int first, final int last, final int divisor) throws InterruptedException, ExecutionException { int amount = 0; // Prepare to execute and store the Futures int threadNum = 2; ExecutorService executor = Executors.newFixedThreadPool(threadNum); List<FutureTask<Integer>> taskList = new ArrayList<FutureTask<Integer>>(); // Start thread for the first half of the numbers FutureTask<Integer> futureTask_1 = new FutureTask<Integer>(new Callable<Integer>() { @Override public Integer call() { return FutureTaskDemo.amountOfDivisibleBy(first, last / 2, divisor); } }); taskList.add(futureTask_1); executor.execute(futureTask_1); // Start thread for the second half of the numbers FutureTask<Integer> futureTask_2 = new FutureTask<Integer>(new Callable<Integer>() { @Override public Integer call() { return FutureTaskDemo.amountOfDivisibleBy(last / 2 + 1, last, divisor); } }); taskList.add(futureTask_2); executor.execute(futureTask_2); // Wait until all results are available and combine them at the same time for (int j = 0; j < threadNum; j++) { FutureTask<Integer> futureTask = taskList.get(j); amount += futureTask.get(); } executor.shutdown(); return amount; } /** * Executing the example. * @param args Command line arguments * @throws ExecutionException * @throws InterruptedException */ public static void main(String[] args) throws InterruptedException, ExecutionException { // Sequential execution long timeStart = Calendar.getInstance().getTimeInMillis(); int result = FutureTaskDemo.amountOfDivisibleBy(0, MAX_NUMBER, 3); long timeEnd = Calendar.getInstance().getTimeInMillis(); long timeNeeded = timeEnd - timeStart; System.out.println("Result : " + result + " calculated in " + timeNeeded + " ms"); // Parallel execution long timeStartFuture = Calendar.getInstance().getTimeInMillis(); int resultFuture = FutureTaskDemo.amountOfDivisibleByFuture(0, MAX_NUMBER, 3); long timeEndFuture = Calendar.getInstance().getTimeInMillis(); long timeNeededFuture = timeEndFuture - timeStartFuture; System.out.println("Result (Future): " + resultFuture + " calculated in " + timeNeededFuture + " ms"); } }

The algorithm (not sure I should call it an algorithm ;)) implemented here is checking how many numbers in a given range can be divided by a certain divisor without remainder. Please keep in mind that this is just a stupid example you could as well calculate something here that tells us why 42 is the Answer to the Ultimate Question of Life, the Universe, and Everything. I personally thought I stick to the more trivial problems for the time being.

The *main*-method is just used to call the two different methods calculating this number and taking the time needed for execution. The first method *amountOfDivisibleBy* is trivial and does not need any further explanation here. The second method *amountOfDivisibleByFuture* is where things are getting interesting.

First of all we are getting ourselves an *Executor* here that is used to start the *Future*-tasks later on, as well as a list in which we will be storing these tasks:

int threadNum = 2; ExecutorService executor = Executors.newFixedThreadPool(threadNum); List<FutureTask<Integer>> taskList = new ArrayList<FutureTask<Integer>>(); |

int threadNum = 2; ExecutorService executor = Executors.newFixedThreadPool(threadNum); List<FutureTask<Integer>> taskList = new ArrayList<FutureTask<Integer>>();

For the sake of keeping this example simple then two *Future*-instances are created exactly the same way, added to the list and executed usind the *Executor*. And this is the nice thing about this. I now have an object (to be precise two objects) that represents the execution of my algorithm.

FutureTask<Integer> futureTask_1 = new FutureTask<Integer>(new Callable<Integer>() { @Override public Integer call() { return FutureTaskDemo.amountOfDivisibleBy(first, last / 2, divisor); } }); taskList.add(futureTask_1); executor.execute(futureTask_1); |

FutureTask<Integer> futureTask_1 = new FutureTask<Integer>(new Callable<Integer>() { @Override public Integer call() { return FutureTaskDemo.amountOfDivisibleBy(first, last / 2, divisor); } }); taskList.add(futureTask_1); executor.execute(futureTask_1);

On these objects I have now different ways on checking if the processing has finished already. In this example it makes sense to go for the “blocking call” using “get” on my *Future*-objects in a loop. This will only return once the processing is finished, thus in this example the first call will probably wait longer and when I reach the second object processing will be done already and the result is returned. Then the results are simply aggregated and returned at the end of the method.

for (int j = 0; j < threadNum; j++) { FutureTask<Integer> futureTask = taskList.get(j); amount += futureTask.get(); } executor.shutdown(); |

for (int j = 0; j < threadNum; j++) { FutureTask<Integer> futureTask = taskList.get(j); amount += futureTask.get(); } executor.shutdown();

Indeed it can be seen that execution time of the method using *Future* is almost twice as fast as the purely sequential execution.

Result : 666666667 calculated in 12500 ms Result (Future): 666666667 calculated in 6922 ms

As often in these kind of articles this is of course a somewhat artificial example, but I hope it shows quite well how nicely *Future* can be used to execute tasks in parallel in Java. And maybe there is some real life example of parallel processing just around the next corner sitting there and waiting to get solved using this.