Where to use callable and where to use Runnable Interface?
Asked Answered
I

5

8

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?

Inadvertency answered 26/5, 2016 at 10:50 Comment(1)
You shouldn't use Callable, if you don't need it. As KISS principle states.Wilcox
P
8

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.

Primogeniture answered 26/5, 2016 at 11:10 Comment(0)
D
4

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?

  1. Use Runnable interface for fire and forget calls, especially when you are not interested in result of the task execution.
  2. There are no extra overheads in implementation of Callable interface.

The key difference from documentation page

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.

Lets check the source code of AbstractExecutorService

public Future<?> submit(Runnable task) {
    if (task == null) throw new NullPointerException();
    RunnableFuture<Object> ftask = newTaskFor(task, null);
    execute(ftask);
    return ftask;
}


public <T> Future<T> submit(Callable<T> task) {
    if (task == null) throw new NullPointerException();
    RunnableFuture<T> ftask = newTaskFor(task);
    execute(ftask);
    return ftask;
}

I don't see any overhead in execution of Callable task as Callable internally uses RunnableFuture<T>

Dodson answered 26/5, 2016 at 11:19 Comment(0)
G
2

One important difference: the run() method in the Runnable interface returns void; the call() method in the Callable interface returns an object of type T. This allows you to access a response object easily.

You can do the same thing with a concrete implementation of Runnable by creating a private data member and providing a getter, but the syntactic sugar is sweet.

Gyral answered 26/5, 2016 at 11:4 Comment(0)
C
0

why so many people use Runnable instead of callable?

Callable is competitively new in jdk, which came with Executor framework, provide more flexibility on thread execution.

Are there any extra overheads in implementing Callable interface in comparison with Runnable Inteface?

I dont think so, it is very straight forward if you follow any standard Executor documentation.

Clime answered 26/5, 2016 at 10:55 Comment(0)
L
0

My doubt is if Callable is capable of doing everything that Runnable, why so many people use Runnable instead of callable?

That question is tantamount to asking, "Why does Java have static types?" An interface is a declaration of a compile-time type signature, nothing more, nothing less; and the only difference between any two interfaces is the compile-time types of the arguments and the return values.

So why does Java have static types? Unfortunately, that question is way out of scope for StackOverflow. You can use Google to find all about staticly typed languages vs. dynamically typed languages.

Also, if you want a glimpse of a different world, you can try writing some Ruby code. There are no interfaces in Ruby because there are no static types. Ruby programmers talk about "Duck Typing", which is another good phrase to Google.

Leverhulme answered 26/5, 2016 at 13:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.