Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where to use callable and where to use Runnable Interface?

I am quite new to Java, I was going through concepts of Multithreading, while going through various implementation of using multithreading, I went through these two concepts. This The difference between the Runnable and Callable interfaces in Java question specifies what is difference between the two and where to use.

My doubt is if Callable is capable of doing everything that Runnable, why so many people use Runnable instead of callable? Are there any extra overheads in implementing Callable interface in comparison with Runnable Inteface?

like image 633
Geek_To_Learn Avatar asked May 26 '16 10:05

Geek_To_Learn


1 Answers

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 Threads.

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 Runnableor 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 Runnables with Callables (this is simple as can be, both are single method interfaces!), stop manipulating Threads in favor of Futures 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 Threads 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 Threads and Runnables (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.

like image 198
GPI Avatar answered Oct 11 '22 23:10

GPI