[java] The difference between the Runnable and Callable interfaces in Java

What is the difference between using the Runnable and Callable interfaces when designing a concurrent thread in Java, why would you choose one over the other?

This question is related to java multithreading interface runnable callable

The answer is


  • A Callable needs to implement call() method while a Runnable needs to implement run() method.
  • A Callable can return a value but a Runnable cannot.
  • A Callable can throw checked exception but a Runnable cannot.
  • A Callable can be used with ExecutorService#invokeXXX(Collection<? extends Callable<T>> tasks) methods but a Runnable cannot be.

    public interface Runnable {
        void run();
    }
    
    public interface Callable<V> {
        V call() throws Exception;
    }
    

+-------------------------------------+--------------------------------------------------------------------------------------------------+
|              Runnable               |                                           Callable<T>                                            |
+-------------------------------------+--------------------------------------------------------------------------------------------------+
| Introduced in Java 1.0 of java.lang | Introduced in Java 1.5 of java.util.concurrent library                                           |
| Runnable cannot be parametrized     | Callable is a parametrized type whose type parameter indicates the return type of its run method |
| Runnable has run() method           | Callable has call() method                                                                       |
| Runnable.run() returns void         | Callable.call() returns a value of Type T                                                        |
| Can not throw Checked Exceptions    | Can throw Checked Exceptions                                                                     |
+-------------------------------------+--------------------------------------------------------------------------------------------------+

The designers of Java felt a need of extending the capabilities of the Runnable interface, but they didn't want to affect the uses of the Runnable interface and probably that was the reason why they went for having a separate interface named Callable in Java 1.5 than changing the already existing Runnable interface which has been a part of Java since Java 1.0. source


Difference between Callable and Runnable are following:

  1. Callable is introduced in JDK 5.0 but Runnable is introduced in JDK 1.0
  2. Callable has call() method but Runnable has run() method.
  3. Callable has call method which returns value but Runnable has run method which doesn't return any value.
  4. call method can throw checked exception but run method can't throw checked exception.
  5. Callable use submit() method to put in task queue but Runnable use execute() method to put in the task queue.

It is a kind of an interface naming convention which matches with functional programming

//Runnable
interface Runnable {
    void run();
}

//Action - throws exception
interface Action {
    void run() throws Exception;
}

//Consumer - consumes a value/values, throws exception
interface Consumer1<T> {
    void accept(T t) throws Exception;
}

//Callable - return result, throws exception
interface Callable<R> {
    R call() throws Exception;
}

//Supplier - returns result, throws exception
interface Supplier<R> {
    R get() throws Exception;
}

//Predicate - consumes a value/values, returns true or false, throws exception
interface Predicate1<T> {
    boolean test(T t) throws Exception;
}

//Function - consumes a value/values, returns result, throws exception
public interface Function1<T, R> {
    R apply(T t) throws Exception;
}

...


Purpose of these interfaces from oracle documentation :

Runnable interface should be implemented by any class whose instances are intended to be executed by a Thread. The class must define a method of no arguments called run.

Callable: A task that returns a result and may throw an exception. Implementors define a single method with no arguments called call. 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.

Other differences:

  1. You can pass Runnable to create a Thread. But you can't create new Thread by passing Callable as parameter. You can pass Callable only to ExecutorService instances.

    Example:

    public class HelloRunnable implements Runnable {
    
        public void run() {
            System.out.println("Hello from a thread!");
        }   
    
        public static void main(String args[]) {
            (new Thread(new HelloRunnable())).start();
        }
    
    }
    
  2. Use Runnable for fire and forget calls. Use Callable to verify the result.

  3. Callable can be passed to invokeAll method unlike Runnable. Methods invokeAny and invokeAll perform the most commonly useful forms of bulk execution, executing a collection of tasks and then waiting for at least one, or all, to complete

  4. Trivial difference : method name to be implemented => run() for Runnable and call() for Callable.


What are the differences in the applications of Runnable and Callable. Is the difference only with the return parameter present in Callable?

Basically, yes. See the answers to this question. And the javadoc for Callable.

What is the need of having both if Callable can do all that Runnable does?

Because the Runnable interface cannot do everything that Callable does!

Runnable has been around since Java 1.0, but Callable was only introduced in Java 1.5 ... to handle use-cases that Runnable does not support. In theory, the Java team could have changed the signature of the Runnable.run() method, but this would have broken binary compatiblity with pre-1.5 code, requiring recoding when migrating old Java code to newer JVMs. That is a BIG NO-NO. Java strives to be backwards compatible ... and that's been one of Java's biggest selling points for business computing.

And, obviously, there are use-cases where a task doesn't need to return a result or throw a checked exception. For those use-cases, using Runnable is more concise than using Callable<Void> and returning a dummy (null) value from the call() method.


Callable interface declares call() method and you need to provide generics as type of Object call() should return -

public interface Callable<V> {
    /**
     * Computes a result, or throws an exception if unable to do so.
     *
     * @return computed result
     * @throws Exception if unable to compute a result
     */
    V call() throws Exception;
}

Runnable on the other hand is interface that declares run() method that is called when you create a Thread with the runnable and call start() on it. You can also directly call run() but that just executes the run() method is same thread.

public interface Runnable {
    /**
     * When an object implementing interface <code>Runnable</code> is used 
     * to create a thread, starting the thread causes the object's 
     * <code>run</code> method to be called in that separately executing 
     * thread. 
     * <p>
     * The general contract of the method <code>run</code> is that it may 
     * take any action whatsoever.
     *
     * @see     java.lang.Thread#run()
     */
    public abstract void run();
}

To summarize few notable Difference are

  1. A Runnable object does not return a result whereas a Callable object returns a result.
  2. A Runnable object cannot throw a checked exception wheras a Callable object can throw an exception.
  3. The Runnable interface has been around since Java 1.0 whereas Callable was only introduced in Java 1.5.

Few similarities include

  1. Instances of the classes that implement Runnable or Callable interfaces are potentially executed by another thread.
  2. Instance of both Callable and Runnable interfaces can be executed by ExecutorService via submit() method.
  3. Both are functional interfaces and can be used in Lambda expressions since Java8.

Methods in ExecutorService interface are

<T> Future<T> submit(Callable<T> task);
Future<?> submit(Runnable task);
<T> Future<T> submit(Runnable task, T result);

Callable and Runnable both is similar to each other and can use in implementing thread. In case of implementing Runnable you must implement run() method but in case of callable you must need to implement call() method, both method works in similar ways but callable call() method have more flexibility.There is some differences between them.

Difference between Runnable and callable as below--

1) The run() method of runnable returns void, means if you want your thread return something which you can use further then you have no choice with Runnable run() method. There is a solution 'Callable', If you want to return any thing in form of object then you should use Callable instead of Runnable. Callable interface have method 'call()' which returns Object.

Method signature - Runnable->

public void run(){}

Callable->

public Object call(){}

2) In case of Runnable run() method if any checked exception arises then you must need to handled with try catch block, but in case of Callable call() method you can throw checked exception as below

 public Object call() throws Exception {}

3) Runnable comes from legacy java 1.0 version, but callable came in Java 1.5 version with Executer framework.

If you are familiar with Executers then you should use Callable instead of Runnable.

Hope you understand.


Let us look at where one would use Runnable and Callable.

Runnable and Callable both run on a different thread than the calling thread. But Callable can return a value and Runnable cannot. So where does this really apply.

Runnable : If you have a fire and forget task then use Runnable. Put your code inside a Runnable and when the run() method is called, you can perform your task. The calling thread really does not care when you perform your task.

Callable : If you are trying to retrieve a value from a task, then use Callable. Now callable on its own will not do the job. You will need a Future that you wrap around your Callable and get your values on future.get (). Here the calling thread will be blocked till the Future comes back with results which in turn is waiting for Callable's call() method to execute.

So think about an interface to a target class where you have both Runnable and Callable wrapped methods defined. The calling class will randomly call your interface methods not knowing which is Runnable and which is Callable. The Runnable methods will execute asynchronously, till a Callable method is called. Here the calling class's thread will block since you are retrieving values from your target class.

NOTE : Inside your target class you can make the calls to Callable and Runnable on a single thread executor, making this mechanism similar to a serial dispatch queue. So as long as the caller calls your Runnable wrapped methods the calling thread will execute really fast without blocking. As soon as it calls a Callable wrapped in Future method it will have to block till all the other queued items are executed. Only then the method will return with values. This is a synchronization mechanism.


I found this in another blog that can explain it a little bit more these differences:

Though both the interfaces are implemented by the classes who wish to execute in a different thread of execution, but there are few differences between the two interface which are:

  • A Callable<V> instance returns a result of type V, whereas a Runnable instance doesn't.
  • A Callable<V> instance may throw checked exceptions, whereas a Runnable instance can't

The designers of Java felt a need of extending the capabilities of the Runnable interface, but they didn't want to affect the uses of the Runnable interface and probably that was the reason why they went for having a separate interface named Callable in Java 1.5 than changing the already existing Runnable.


As it was already mentioned here Callable is relatively new interface and it was introduced as a part of concurrency package. Both Callable and Runnable can be used with executors. Class Thread (that implements Runnable itself) supports Runnable only.

You can still use Runnable with executors. The advantage of Callable that you can send it to executor and immediately get back Future result that will be updated when the execution is finished. The same may be implemented with Runnable, but in this case you have to manage the results yourself. For example you can create results queue that will hold all results. Other thread can wait on this queue and deal with results that arrive.


Runnable (vs) Callable comes into point when we are using Executer framework.

ExecutorService is a subinterface of Executor, which accepts both Runnable and Callable tasks.

Earlier Multi-Threading can be achieved using Interface RunnableSince 1.0, but here the problem is after completing the thread task we are unable to collect the Threads information. In-order to collect the data we may use Static fields.

Example Separate threads to collect each student data.

static HashMap<String, List> multiTasksData = new HashMap();
public static void main(String[] args) {
    Thread t1 = new Thread( new RunnableImpl(1), "T1" );
    Thread t2 = new Thread( new RunnableImpl(2), "T2" );
    Thread t3 = new Thread( new RunnableImpl(3), "T3" );

    multiTasksData.put("T1", new ArrayList() ); // later get the value and update it.
    multiTasksData.put("T2", new ArrayList() );
    multiTasksData.put("T3", new ArrayList() );
}

To resolve this problem they have introduced Callable<V>Since 1.5 which returns a result and may throw an exception.

  • Single Abstract Method : Both Callable and Runnable interface have a single abstract method, which means they can be used in lambda expressions in java 8.

    public interface Runnable {
    public void run();
    }
    
    public interface Callable<Object> {
        public Object call() throws Exception;
    }
    

There are a few different ways to delegate tasks for execution to an ExecutorService.

  • execute(Runnable task):void crates new thread but not blocks main thread or caller thread as this method return void.
  • submit(Callable<?>):Future<?>, submit(Runnable):Future<?> crates new thread and blocks main thread when you are using future.get().

Example of using Interfaces Runnable, Callable with Executor framework.

class CallableTask implements Callable<Integer> {
    private int num = 0;
    public CallableTask(int num) {
        this.num = num;
    }
    @Override
    public Integer call() throws Exception {
        String threadName = Thread.currentThread().getName();
        System.out.println(threadName + " : Started Task...");

        for (int i = 0; i < 5; i++) {
            System.out.println(i + " : " + threadName + " : " + num);
            num = num + i;
            MainThread_Wait_TillWorkerThreadsComplete.sleep(1);
        }
        System.out.println(threadName + " : Completed Task. Final Value : "+ num);

        return num;
    }
}
class RunnableTask implements Runnable {
    private int num = 0;
    public RunnableTask(int num) {
        this.num = num;
    }
    @Override
    public void run() {
        String threadName = Thread.currentThread().getName();
        System.out.println(threadName + " : Started Task...");

        for (int i = 0; i < 5; i++) {
            System.out.println(i + " : " + threadName + " : " + num);
            num = num + i;
            MainThread_Wait_TillWorkerThreadsComplete.sleep(1);
        }
        System.out.println(threadName + " : Completed Task. Final Value : "+ num);
    }
}
public class MainThread_Wait_TillWorkerThreadsComplete {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        System.out.println("Main Thread start...");
        Instant start = java.time.Instant.now();

        runnableThreads();
        callableThreads();

        Instant end = java.time.Instant.now();
        Duration between = java.time.Duration.between(start, end);
        System.out.format("Time taken : %02d:%02d.%04d \n", between.toMinutes(), between.getSeconds(), between.toMillis()); 

        System.out.println("Main Thread completed...");
    }
    public static void runnableThreads() throws InterruptedException, ExecutionException {
        ExecutorService executor = Executors.newFixedThreadPool(4);
        Future<?> f1 = executor.submit( new RunnableTask(5) );
        Future<?> f2 = executor.submit( new RunnableTask(2) );
        Future<?> f3 = executor.submit( new RunnableTask(1) );

        // Waits until pool-thread complete, return null upon successful completion.
        System.out.println("F1 : "+ f1.get());
        System.out.println("F2 : "+ f2.get());
        System.out.println("F3 : "+ f3.get());

        executor.shutdown();
    }
    public static void callableThreads() throws InterruptedException, ExecutionException {
        ExecutorService executor = Executors.newFixedThreadPool(4);
        Future<Integer> f1 = executor.submit( new CallableTask(5) );
        Future<Integer> f2 = executor.submit( new CallableTask(2) );
        Future<Integer> f3 = executor.submit( new CallableTask(1) );

        // Waits until pool-thread complete, returns the result.
        System.out.println("F1 : "+ f1.get());
        System.out.println("F2 : "+ f2.get());
        System.out.println("F3 : "+ f3.get());

        executor.shutdown();
    }
}

Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to multithreading

How can compare-and-swap be used for a wait-free mutual exclusion for any shared data structure? Waiting until the task finishes What is the difference between Task.Run() and Task.Factory.StartNew() Why is setState in reactjs Async instead of Sync? What exactly is std::atomic? Calling async method on button click WAITING at sun.misc.Unsafe.park(Native Method) How to use background thread in swift? What is the use of static synchronized method in java? Locking pattern for proper use of .NET MemoryCache

Examples related to interface

Cast object to interface in TypeScript When to use Interface and Model in TypeScript / Angular Is there a way to create interfaces in ES6 / Node 4? Can a normal Class implement multiple interfaces? When to use: Java 8+ interface default method, vs. abstract method How should I have explained the difference between an Interface and an Abstract class? When do I have to use interfaces instead of abstract classes? How to extend a class in python? Interface type check with Typescript Abstract Class vs Interface in C++

Examples related to runnable

In a simple to understand explanation, what is Runnable in Java? new Runnable() but no new thread? What's the difference between Thread start() and Runnable run() Naming threads and thread-pools of ExecutorService Runnable with a parameter? "implements Runnable" vs "extends Thread" in Java The difference between the Runnable and Callable interfaces in Java

Examples related to callable

How do I fix this "TypeError: 'str' object is not callable" error? Why does the 'int' object is not callable error occur when using the sum() function? TypeError: 'list' object is not callable while trying to access a list The difference between the Runnable and Callable interfaces in Java What is a "callable"?