ExecutorService with Callable and Future

In last post I talked about ExecutorService basics.

Let us take it forward to understand usage of Future keyword. So far we have seen Executor service usage to start executing a thread in controlled way. What if we need to get a returned object from the thread being executed. Callable interface comes to help. Instead of implmenting Runnable, we can implement Callable to create thread. In this case we will override call() method method instead of run().

From Javadocs: The Callable interface is similar to Runnable, in that both are designed for classes whose instances are potentially executed by another thread. A Runnable, however, does not return a result and cannot throw a checked exception.

The result of callable class is retrived in Future instance. Instead of executor.execute, we will call submit method which forces ExecutorService to return the Future instance. execute can also be used with Runnable instance, but in that case it will return null on completion as run() method cannot return an object.

Here is an example

public class CallableTest {
int num=1;
public static void main(String s[])
{
ExecutorService executor = Executors.newFixedThreadPool(5);
//for(int i=0;i<10;i++) { Future ft=executor.submit(new RunTest());
Future ft1=executor.submit(new RunTest2());
System.out.println(“step 1”);
try {
CallableTest ct=ft.get();
System.out.println(“ct val:”+ct.num);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(“step 2”);
try {
System.out.println(ft1.get());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(“step 3”);

}
executor.shutdown();
}
}

class RunTest implements Callable
{
@Override
public CallableTest call() throws Exception {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
CallableTest ct=new CallableTest();
ct.num=10;
// TODO Auto-generated method stub
return ct;
}

}

class RunTest2 implements Runnable
{
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}

Further Reading

http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Callable.html