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?
-
2For additional discussion, after reading this page, see [Shall Callable be preferred over Runnable?](http://stackoverflow.com/q/16757142/1005481) – barfuin Jun 18 '13 at 08:04
14 Answers
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.

- 698,415
- 94
- 811
- 1,216

- 96,051
- 25
- 122
- 132
-
6Exactly. Also Runnable tasks can be run using the Thread class or ExecutorService whereas Callables can be run only using the latter. – cem çetin Feb 19 '22 at 12:51
What are the differences in the applications of
Runnable
andCallable
. Is the difference only with the return parameter present inCallable
?
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 thatRunnable
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.
-
16
-
8@prash - the basic facts are to be found in old textbooks. Like the first edition of Java in a Nutshell. – Stephen C May 29 '14 at 11:40
-
7
-
1@StephenC If I read your answer correctly, you're suggesting that `Runnable` exists (largely) for backward compatibility reasons. But aren't there situations where it's unnecessary or too expensive to implement (or to require) `Callable` interface (e.g., in `ScheduledFuture> ScheduledExecutorService.schedule(Runnable command, long delay, TimeUnit unit)`) ? So isn't there a benefit to maintaining both interfaces in the language even the history didn't force the current outcome? – max May 04 '17 at 11:46
-
@max - I disagree with that. If you look at those API methods, the complexity and cost are not *caused by* the use of `Callable` as the argument type. The C & C are inherent in the functionality. (Or to put it another way, those methods would be equally C & Cly if they had used `Runnable` as the argument type.) So, no that is not a reason to keep both `Callable` and `Runnable`. – Stephen C Jul 04 '17 at 22:36
-
@StephenC My wording was bad. What I meant to say, is that your last paragraph seems to provide an argument in favor of `Runnable` being available for situations where there's no point requiring the client to support `Callable` interface (not that it's hard to support, but it still means the client needs to add unused boilerplate code). – max Jul 04 '17 at 22:44
-
1@max - Well I said that, and I still agree with that. However, that is a secondary reason. But even so, I suspect that `Runnable` *would have been* modified if there had not been an imperative to maintain compatibility. The "boilerplate" of `return null;` is a weak argument. (At least, that would have been my decision ... in the hypothetical context where you could ignore backwards compatibility.) – Stephen C Jul 04 '17 at 22:51
- 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; }

- 2,281
- 2
- 24
- 38
-
21ExecutorService.submit(Runnable task) also exists and is very useful – Yair Kukielka May 29 '15 at 18:00
-
Runnable can also be used with ExecutorService by following ways- 1) ExecutorService.execute(Runnable) 2) ExecutorService.submit(Runnable) – Azam Khan Nov 11 '16 at 06:08
-
2Also there is Executor.submit(Callable
task) but you can't invokeAll or invokeAny with collection of Runnable tasks Collection extends Callable – nikli Sep 02 '17 at 11:48> tasks
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'tThe designers of Java felt a need of extending the capabilities of the
Runnable
interface, but they didn't want to affect the uses of theRunnable
interface and probably that was the reason why they went for having a separate interface namedCallable
in Java 1.5 than changing the already existingRunnable
interface which has been a part of Java since Java 1.0.
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.

- 1,850
- 18
- 15
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);

- 66,731
- 38
- 279
- 289
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 calledrun
.
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
. 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.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 bulk execution => executing a collection of tasks and then waiting for at least one OR all, to completeTrivial difference : method name to be implemented =>
run()
forRunnable
andcall()
forCallable
.

- 37,698
- 11
- 250
- 211
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.

- 114,158
- 16
- 130
- 208
-
i wonder what is the example on a thread throwing exception out in java? will the main thread be able to catch that exception? If not, i wouldn't use Callable. Alex, do you have some insight on this? thanks! – trillions Mar 25 '14 at 09:04
-
1Code running in custom thread as any other code can throw exception. To catch it in other thread you have to perform some efforts either using custom notification mechanism (e.g. based on listeners) or by using `Future` or by adding hook that catches all uncought exceptions: http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#setDefaultUncaughtExceptionHandler%28java.lang.Thread.UncaughtExceptionHandler%29 – AlexR Mar 25 '14 at 09:27
-
-
2I upvoted this answer because it asserts (correctly if taken at face value) one must use the thread pool model with callable objects. The apparently unfortunate thing about this is that one cannot extend `Thread` to make meaningful use of the `Callable` interface so that a single thread can be customised to do callable things and other things the developer might want. If anyone who reads this comment thinks I am wrong, I'd like to know better... – Oct 20 '15 at 03:06
-
1@user1941660 If you meant literally a thread pool, not correct. You can pass either `Runnable` or `Callable` to an executor service backed by a single thread rather than a thread pool. See `Executors.newSingleThreadExecutor()` and `Executors.newSingleThreadScheduledExecutor()`. If by "thread pool" you meant the Executors framework, understand that the point of adding the Executors framework in Java 5 was to relieve developers from having to deal with `Thread` class directly. Generally, you should no longer be extending `Thread` for your concurrency work. – Basil Bourque Dec 26 '20 at 07:28
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.

- 1,391
- 14
- 29

- 1,580
- 15
- 12
-
It's important to emphasize that **checked Exception**,not the RuntimeException – BertKing Jul 22 '19 at 13:00
+----------------------------------------+--------------------------------------------------------------------------------------------------+
| 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

- 72,055
- 26
- 237
- 180
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.

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

- 9,250
- 2
- 69
- 74
Java functional interfaces
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
//BiConsumer,
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
//BiFunction, Function3...
public interface Function1<T, R> {
R apply(T t) throws Exception;
}
...
//Executor
public interface Executor {
void execute(Runnable command);
}

- 29,217
- 8
- 193
- 205
-
From where did you find this ? I can't find the Action interface that match you example in Java – Erwan Daniel Oct 20 '20 at 12:04
-
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.

- 109
- 4