How to Use Callable and FutureTask
Introduction
Since Java 1.5 there has been a new set of objects under java.util.concurrent. This package has a number of different classes including thread queues. I could have used those when I was programming with Java 1.2! When I started looking at the new toys I became hesitant. What is this Callable thing and what is the Future? It turns out that there is nothing wrong with a Future and Callable. In fact, they are what I have been hoping, looking for in my Java career.
Differences Between Callable and Runnable
Callable is what Runnable hoped to become. Callable’s only method is “T call().” What makes it so neat is that it returns something. This is a step above having to create a getter for the answer to a task. While this is cool, there needs to be a way to get at the returned value.
The Future is here
Future has a way to get the value out when the Callable is done. The function is get() or get(long timeout, TimeUnit unit). This is the equivalent of calling thread.join(); runnable.getValue() at the same time.
Example
I created a class called CounterCallable. All it does is add numbers from the variable start to variable end.
CounterCallable
package org.mathison.futurecallable; import java.util.concurrent.Callable; /** * * @author Daryl */ public class CounterCallable implements Callable { private long start; private long end; public CounterCallable(long start, long end) { this.start = start; this.end = end; } @Override public SumTimeAnswer call() throws Exception { long sum = 0; long startTime = System.currentTimeMillis(); for(long i = start; i <= end; i++){ sum += i; } long endTime = System.currentTimeMillis(); return new SumTimeAnswer(sum, endTime - startTime); } }
SumTimeAnswer
Class SumTimeAnswer is really a simple getter class that holds the sum and the amount of time it took to do the operation.
package org.mathison.futurecallable; /** * * @author Daryl */ public class SumTimeAnswer { private long timeToFinish; private long sum; public SumTimeAnswer(long sum, long timeToFinish) { this.sum = sum; this.timeToFinish = timeToFinish; } public long getTimeToFinish() { return timeToFinish; } public long getSum() { return sum; } }
App
App is just a main class pulling everything together
package org.mathison.futurecallable; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.FutureTask; /** * Hello world! * */ public class App { public static final long BEGIN = 0; public static final long END = 100000; public static void main( String[] args ) { FutureTask task = new FutureTask(new CounterCallable(BEGIN, END)); FutureTask firstHalf = new FutureTask(new CounterCallable(BEGIN, END/2)); FutureTask secondHalf = new FutureTask(new CounterCallable(END/2 + 1, END)); ExecutorService pool = Executors.newSingleThreadExecutor(); pool.submit(task); pool.submit(firstHalf); pool.submit(secondHalf); try { SumTimeAnswer taskAnswer = task.get(); System.out.println("just one thread Time: " + taskAnswer.getTimeToFinish() + " Total: " + taskAnswer.getSum()); SumTimeAnswer taskFirstAnswer = firstHalf.get(); SumTimeAnswer taskSecondAnswer = secondHalf.get(); long totalTime = taskFirstAnswer.getTimeToFinish() + taskSecondAnswer.getTimeToFinish(); long totalSum = taskFirstAnswer.getSum() + taskSecondAnswer.getSum(); System.out.println("Two thread time: " + totalTime + " Total: " + totalSum); } catch(CancellationException | InterruptedException | ExecutionException e) { e.printStackTrace(); } pool.shutdown(); } }
Conclusion
In this post, classes Callable and FutureTask were used to demonstrate how to use the java.util.concurrent package.
Reference: | How to Use Callable and FutureTask from our JCG partner Daryl Mathison at the Daryl Mathison’s Java Blog blog. |
Awesome article!
Thanks, more samples please ^ ^