The difference between the Runnable and Callable interfaces in Java

JavaMultithreadingInterfaceRunnableCallable

Java Problem Overview


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?

Java Solutions


Solution 1 - Java

See explanation here.

> 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.

Solution 2 - Java

> 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.

Solution 3 - Java

  • 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;
      }
    

Solution 4 - Java

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.

Solution 5 - Java

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.

Solution 6 - Java

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);

Solution 7 - Java

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.

Solution 8 - Java

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.

Solution 9 - Java

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.

Solution 10 - Java

+----------------------------------------+--------------------------------------------------------------------------------------------------+
|              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 generic value V                                                        |
| No way to propagate checked exceptions | Callable's call()“throws Exception” clause so we can easily propagate checked exceptions further |                                                                     |
+----------------------------------------+--------------------------------------------------------------------------------------------------+

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

Solution 11 - Java

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.

Solution 12 - Java

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();
	}
}

Solution 13 - Java

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;
}

...

//Executor
public interface Executor {
    void execute(Runnable command);
}

Solution 14 - Java

In addition to all other answers:

We can not pass/use Callable to an individual thread for execution i.e. Callable can be used only in Executor Framework. But, Runnable can be passed to an individual thread for execution (new Thread(new CustomRunnable())), as well as can be used in Executor Framework.

Solution 15 - Java

Runnable interface

  • It is a part of java.lang package since Java 1.0
  • It cannot throw a checked Exception.
  • It cannot return the return of computation.
  • In a runnable interface, one needs to override the run() method in Java.

Callable interface

  • It is a part of the java.util.concurrent package since Java 1.5.

  • It can throw a checked Exception.

  • It can return the result of the parallel processing of a task.

  • In order to use Callable, you need to override the call()

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionScottmView Question on Stackoverflow
Solution 1 - JavaJorge FerreiraView Answer on Stackoverflow
Solution 2 - JavaStephen CView Answer on Stackoverflow
Solution 3 - JavanikliView Answer on Stackoverflow
Solution 4 - JavaamoranView Answer on Stackoverflow
Solution 5 - JavaKris SubramanianView Answer on Stackoverflow
Solution 6 - JavaAniket ThakurView Answer on Stackoverflow
Solution 7 - JavaRavindra babuView Answer on Stackoverflow
Solution 8 - JavaAlexRView Answer on Stackoverflow
Solution 9 - JavaRaman GuptaView Answer on Stackoverflow
Solution 10 - JavaPremrajView Answer on Stackoverflow
Solution 11 - JavaSudhakar PandeyView Answer on Stackoverflow
Solution 12 - JavaYashView Answer on Stackoverflow
Solution 13 - JavayoAlex5View Answer on Stackoverflow
Solution 14 - JavaAbhale AmolView Answer on Stackoverflow
Solution 15 - JavaSaurabh DhageView Answer on Stackoverflow