Sunday, December 19, 2010

Call me!


Today you will have a great occasion to call someone you would never expect to call... a thread. We talked already about the concurrency on the blog: Threads part 1: The basics and Threads part 2: functions overview. But the problem with the previous solution to achieve simultaneous computation is the lack of explicit mechanism to retrieve the result from a thread. As luck would have it, since Java 1.5 we have an access to a new interface – Callable. In comparison to Runnable there are a few significant differences:
  • with Callable you can easily return a result of another execution thread.
  • with Callable you can throw checked exceptions.
  • with Callable you have to use a thread executor.
So far so good. Now, to get more familiar with it, let's have a look at some code:

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;


class Computation implements Callable<Integer> {

@Override
public Integer call() throws Exception {
int result = 0;
for(int i = 0; i < 10000; i++) {
for(int j = 0; j < 100000; j++) {
// Some taught computation
result += (i * j) - (i * j) + 1;
}
}
return result;
}

}

public class CallableExample {
public static void main(String[] args) {
ExecutorService pool = Executors.newFixedThreadPool(5);
Future<Integer> f1 = pool.submit(new Computation());
for(int i = 0; i < 10; i++) {
System.out.println(i);
}
try {
System.out.println(f1.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
pool.shutdown();
}
}

Ok, there are a few new elements regarding Callable. First of all, if we implement the Callable interface, we have to implement T call() method. This is where the action takes place, it's a method corresponding to the run() method from Runnable interface. And the other important thing – it's the place where we can throw an exception (Exception or any subclass).
When the class implementing Callable interface is ready, we can instantiate it and run through a submit() method of a thread executor what happens in line 27. The submit() method will return some implementation of a Future interface. It represents the thread's computation and provides a few useful methods, among others:
boolean isDone();
which returns true if the task is completed.
T get()
which returns a result of a task of type T, or if the task is not completed yet it waits until it's finished. Actually this could be achieved with a wait() method using a Runnable interface and calling it on the instance of a thread from the main execution thread.

And that's it. I'm sure that the above information and the sample code will let you use the Callable interface in appropriate way.

No comments:

Post a Comment