The Callable
interface in Java is similar to the Runnable
interface, but it can return a result and is able to throw an Exception.
Callable
is often used in the context of concurrent processing, in combination with the ExecutorService
to run multiple tasks in parallel.
Here is the Callable
interface definition:
@FunctionalInterface public interface Callable<V> { V call() throws Exception; }
The Callable
interface has a single method call()
, which returns a value. The type of this return value is defined by the generic parameter V
.
Here is an example of how to use Callable
:
Callable<Integer> task = () -> { try { TimeUnit.SECONDS.sleep(1); return 123; } catch (InterruptedException e) { throw new IllegalStateException("task interrupted", e); } }; ExecutorService executor = Executors.newFixedThreadPool(1); Future<Integer> future = executor.submit(task); System.out.println("future done? " + future.isDone()); Integer result = future.get(); System.out.println("future done? " + future.isDone()); System.out.print("resu
lt: " + result);
In this example, we create a Callable
task that sleeps for one second and then returns 123. We submit this task to an ExecutorService
, which returns a Future
.
The Future
can be used to check if the computation is done and to retrieve the result of the computation. The future.get()
method blocks until the computation is done and then returns the result.
Runnable vs Callable:
1) Existence and Availability
The first and most important difference between Runnable and Callable interface is that Runnable is available in Java right from the beginning i.e. JDK 1.0 while Callable was later added to Java 5, so you cannot use Callable before Java 5.
2) Result
The second key difference between Callable and Runnable is that Callable can return the result of the parallel processing of a task. It returns a Future object, which represents the lifecycle of a task and provides methods to check if the task has been completed or canceled, retrieve the result or cancel the task. Since the return type of Runnable's run() method is void, it cannot return anything.
3) Checked Exception
Another worth noting difference between these two interfaces is that Callable's call() method can throw Checked exception while Runnable's run() method cannot throw checked exception.
4) The call() vs run() methods
In order to use Callable, you need to override the call() method while in order to use the Runnable interface you need to override the run() method in Java.
5) Execution
There is one limitation while using the Callable interface in Java that you cannot pass it to Thread as you pass the Runnable instance.
There is no constructor defined in the Thread class which accepts a Callable interface. So in order to execute a Callable instance, you need to use the ExecutorService interface of the Java 5 Executor framework.
This interface defines the submit() method which accepts a Callable instance and returns a Future object which holds the result of computation as shown below:
Future result = exec.submit(aCallable);
result = holder.get();
Remember, Future.get() is a blocking method and blocks until execution is finished, so you should always call this method with a timeout to avoid deadlock or livelock in your application.
Runnable vs Callable |
Post a Comment