I have understood the difference between Runnable
and Callable
interface in Java. From Java 1.5 additional features has been added to Runnable
I prefer Callable
s, but in those rare instances you might need a Callable
to be Runnable
, you can easily implement both by adding a run()
method like this to your Callable
.
public void run(){
try{
call();
} catch (Exception e){
e.printStackTrace(); // or however you log errors
}
}
In Java 8, you can also make an interface to do the same thing for you:
public interface CallableRunnable<T> extends Callable<T>, Runnable {
default void run(){
try {
call();
} catch (Exception e) {
e.printStackTrace(); // or however you log errors
}
}
}
Then you just have to change anything that implements Callable<T>
to implements CallableRunnable<T>
.That way, your jobs can always be called by any method that requires either. Of course, if you need specific error handling, you can still override the run() method to handle the exceptions thrown by your call()
method. You could even implement a method to do so:
public interface CallableRunnable<T> extends Callable<T>, Runnable {
default void run(){
try {
call();
} catch (Exception e) {
handleCallExceptions(e);
}
}
default void handleCallExceptions(Exception e){
e.printStackTrace();
}
}
Then any special exception handling only needs to implement its own handleExceptions(Exception)
method... but you don't have to if you don't need to. I prefer this because it allows you to have an implementation that uses your logging framework, etc.
Both have their uses, and both are supported by the Executor framework in java.util.concurrent. Runnable has been around longer, but it is still in use and not discouraged.
Callables can throw exceptions and return values, which makes them the better abstraction for result-bearing tasks (such as fetching a resource from the network, performing an expensive computation of a value, and the like) [from Java Concurrency in Practice by Goetz, Bloch et. al., the standard work on Java concurrency].
So, if you are designing an API, I would suggest using Callables when possible. If you are sure that the tasks will not return values and will not throw exceptions, then Runnables are also a valid choice. There is no black and white here, especially because Runnables can easily be wrapped in Callables and vice versa.
As an aside, note that your Callable implementation need not declare throws Exception
; the fact that Callable itself declares it is only to allow implementors to throw any checked exceptions. Callers of your Callable who rely solely on the Callable interface will have to write exception handling code, though.
Also note that Callables need not return a value; you can simply declare your Callable to return Void
(with capital 'V
').
IMHO, Runnable is a better type to use when taking as argument a function which
Don't forget that Callable.call()
throws Exception. That means that if you take a Callable as argument, this Callable can throw any kind of exception, and you must have a way to handle them all in a correct way. If you can't do that, it's better to let the implementor of the Callable handle the exception as he wants to, and make the argument a Runnable to make that clear.
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.
Use case of not using Callable
: ScheduledExecutorService.scheduleAtFixedRate
and scheduleWithFixedDelay
accepts only Runnable
.