The difference between the Runnable and Callable interfaces in Java
JavaMultithreadingInterfaceRunnableCallableJava 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 implementcall()
method while aRunnable
needs to implementrun()
method. -
A
Callable
can return a value but aRunnable
cannot. -
A
Callable
can throw checked exception but aRunnable
cannot. -
A
Callable
can be used withExecutorService#invokeXXX(Collection<? extends Callable<T>> tasks)
methods but aRunnable
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 typeV
, whereas aRunnable
instance doesn't. - A
Callable<V>
instance may throw checked exceptions, whereas aRunnable
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
- A
Runnable
object does not return a result whereas aCallable
object returns a result. - A
Runnable
object cannot throw a checked exception wheras aCallable
object can throw an exception. - The
Runnable
interface has been around since Java 1.0 whereasCallable
was only introduced in Java 1.5.
Few similarities include
-
Instances of the classes that implement Runnable or Callable interfaces are potentially executed by another thread.
-
Instance of both Callable and Runnable interfaces can be executed by ExecutorService via submit() method.
-
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:
-
You can pass
Runnable
to create a Thread. But you can't create new Thread by passingCallable
as parameter. You can pass Callable only toExecutorService
instances.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(); } }
-
Use
Runnable
for fire and forget calls. UseCallable
to verify the result. -
Callable
can be passed to invokeAll method unlikeRunnable
. MethodsinvokeAny
andinvokeAll
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 -
Trivial difference : method name to be implemented =>
run()
forRunnable
andcall()
forCallable
.
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:
- Callable is introduced in JDK 5.0 but Runnable is introduced in JDK 1.0
- Callable has call() method but Runnable has run() method.
- Callable has call method which returns value but Runnable has run method which doesn't return any value.
- call method can throw checked exception but run method can't throw checked exception.
- 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--
- 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 Runnable
Since 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()