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?
Solution 1:
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:
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.
Solution 3:
- 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:
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:
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.