java.util.concurrent.Callable interface

Callable interface is similar to Runnable except that its call() method returns a value and can throw a checked exception, while run() method of Runnable interface is void and cannot throw any checked exception. Like Runnable, Callable is a functional interface, which has the following definition :

@FunctionalInterface

public interface Callable<V> {

    V call() throws Exception;

}

The ExecutorService includes an overloaded version of the submit() method that takes a Callable object and returns a generic Future<t> object : <T> Future<T> submit(Callable<T> task)

Unlike Runnable, in which the get() methods always return null, the get() methods on a Future object return the matching generic type or null. The following example shows the use of Callback :

public class CallableExample {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService service = null;
        try {
            service = Executors.newSingleThreadExecutor();
            Future<Integer> result = service.submit(() -> 30 + 11);
            System.out.println(result.get());
        } finally {
            if (service != null) {
                service.shutdown();
            }
        }
    }
}

The output of the Callable result, 41 in this case, is retrieved and printed out in the console.

Differences between Runnable and Callable

Since Callable supports a return type when used with ExecutorService, it is often preferred over Runnable when using Concurrency API.

Besides having a return type, the Callable interface also supports checked exceptions, whereas the Runnable interface does not without embedded try/catch block. In the examples below :

service.submit(() -> {Thread.sleep(1000); return null;}); // COMPILES

service.submit(() -> {Thread.sleep(1000);}); // DOES NOT COMPILE

the first line will compile, and the second line will not. Recall that Thread.sleep() throws a checked InterruptedException. Since the first lambda expression has a return type, the compiler treats this as a Callable expression that supports checked exceptions. The second lambda expression does not return a value; therefore, the compiler treats this as a Runnable expression. Since Runnable methods do not support checked exceptions, the compiler will report an error trying to compile this code snippet.

Both interfaces are interchangeable in situations where the lambda does not throw an exception and there is no return type.

Leave a Reply

Your email address will not be published. Required fields are marked *