How to Use Callable and FutureTask

Standard

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.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s