Before there was the java.util.concurrent
package, which landed in the Java 5 release, there was really no other options to doing concurrent computation, but to directly manipulate Thread
s.
You could manipulate threads directly, e.g. by subclassing:
public class MyThread extends Thread {
public void run() {
myComputation();
}
}
Or you could do the same by creating a Runnable
, which was the preferred way (mainly because you do not need to subclass anything, which provides a clear separation of concern, better code reuse or generally, a better composition):
public class MyRunnable implements Runnable {
public void run() {
mycomputation();
}
}
new Thread(new MyRunnable()).start();
But no matter which way you used, you had to create, launch, manipulate, join on threads. Which has drawbacks: how many threads can you create? Is this expensive? (At some point, it is, although it became cheaper and cheaper with each JVM implementation.)
Plus, this API itself has limitations that the developer had to overcome: what if I want to return a value from a Runnable
, seeing the signature does not allow it anyway? How can I know if my Runnable
failed with an Exception
? There things such as exception handlers and the like to allow for that with threads, but it was quiet a repetitive, error prone, task.
Enters the java.util.concurrent
package! It offers an answer to all this (and more)!
You want to reuse threads for more than one "unit of work" (be it a Runnable
or not?): you can. Want to know if the "unit of work" completed or failed: you can. Want to return a value: you can. Want to dynamically prioritize some tasks above others? Sure. Need the ability to schedule tasks? Can do. And so on.
Replace your Runnable
s with Callable
s (this is simple as can be, both are single method interfaces!), stop manipulating Thread
s in favor of Future
s and leave the plumbing to ExecutorService
.
My doubt is if Callable is capable of doing everything that Runnable, why so many people use Runnable instead of callable?
Maybe they do have old code (Java 1.4?). Maybe they are not aware of the benefits of the higher level abstractions, and prefer the low level Thread
stuff?
Generally speaking, there is absolutely no reason to prefer using Thread
s since the concurrent API came.
Are there any extra overheads in implementing Callable interface in comparison with Runnable Interface?
In "implementing Callable
" vs Runnable
, no there is none. But there is a cost to the new Callable
stuff because internally, it all comes back down to Thread
s and Runnable
s (at least, the current implementations do this). But you might actually gain performance, because of new capabilities like easier thread reuse!
So, yes, the concurrent API has its cost, but it is absolutely, completely negligible in any standard use case, but it also has new strengths that make it better in many ways, including performance.
Plus, you get massive new possibilities from the API, as already stated (see the Fork/Join framework, see the parallel streams in Java 8, ...), and reduce the need for any kink of "custom", "self made" concurrency code for said functionalities, which is notoriously hard to get right.
The benefit/cost ratio completely favors the "new" concurrent API.