Difference between Callable and Runnable in Java? call() vs run() method

Hello guys, the difference between the Callable and Runnable interface in Java is one of the interesting questions from my list of Top 15 Java multi-threading questions, and it’s also very popular in various Java Interviews. The Callable interface is newer than the Runnable interface and was added on Java 5 release along with other major changes e.g. Generics, Enum, Static imports, and variable argument method. Though both Callable and Runnable interfaces are designed to represent a task, which can be executed by any thread, there is some significant difference between them. 

In my opinion, the major difference between the Callable and Runnable interface is that Callable can return the result of an operation performed inside the call() method, which was one of the limitations of the Runnable interface. It has return type as void()  which means it cannot return any result. 
 
Another significant difference between the Runnable and Callable interfaces is the ability to throw checked exceptions. The Callable interface can throw checked exceptions because its call method throws Exceptions while run() method doesn't throw any checked Exception. 

By the way, sometimes this question is also asked as a follow-up question of another classic difference between Runnable and Thread in Java. Commonly FutureTask is used along with Callable to get the result of asynchronous computation task performed in the call() method.




Callable vs Runnable interface in Java

As I explained the major differences between a Callable and Runnable interface in the last section. Sometimes this question is also asked as the difference between call() and run() method in Java. All the points discussed here are equally related to that question as well. Let's see them in point format for better understanding :


1) The Runnable interface is older than Callable which is there from JDK 1.0, while Callable is added on Java 5.0.

2) Runnable interface has run() method to define task while Callable interface uses call() method for task definition.

3) run() method does not return any value, its return type is void while the call method returns a value. The Callable interface is a generic parameterized interface and a Type of value is provided when an instance of Callable implementation is created.

4) Another difference in the run and call method is that the run method can not throw checked exceptions while the call method can throw checked exceptions in Java.

Now that you have seen the difference between Runnable and Callable in Java, let's see one example of both of them to truly understand how and when to use them:

Runnable vs Callable in Java



Callable Example in Java

Here is a simple example of how to use Callable in Java. In this example, I have created a new ExecutorService with a fixed thread pool size of 1. We then create a new Callable that returns a string, and submit it to the ExecutorService using the submit method. 

This returns a Future object that we can use to get the result of the Callable once it has completed. We block until the result is available by calling the get method on the Future, and then print the result. Finally, you need to shut down the ExecutorService.

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class CallableExample {

    public static void main(String[] args) throws Exception {

        // Create a new ExecutorService with a fixed thread pool size of 1
        ExecutorService executor = Executors.newFixedThreadPool(1);

        // Create a new Callable that returns a string
        Callable<String> task = () -> {
            System.out.println("Task running...");
            Thread.sleep(2000);
            return "Hello, World!";
        };

        // Submit the Callable to the ExecutorService and get a Future object
        Future<String> future = executor.submit(task);

        // Block until the result is available
        String result = future.get();

        // Print the result
        System.out.println("Result: " + result);

        // Shut down the ExecutorService
        executor.shutdown();
    }
}

When you run the code, it will print the following output:

Task running...
Result: Hello, World!

The Callable implementation simply prints "Task running..." to the console then sleeps for 2 seconds to simulate some work being done, and then returns the string "Hello, World!"

When the Future object is obtained and its get() method is called, the thread will block until the result is available. In this case, the result is the string "Hello, World!", which is then printed to the console.


And, now let's see an example of Runnable interface in Java:


Runnable Example in Java

Here is a simple example of Runnable interface in Java. In this example, I have create a new Runnable implementation called MyRunnable which simply prints "Hello, World!" to the console. We then create a new Thread object and pass in the MyRunnable instance to its constructor. 

Finally, we call the start() method on the Thread object to start the thread and execute the run() method of the MyRunnable instance in the background. When you run this code, you should see "Hello, World!" printed to the console.
public class RunnableExample {

    public static void main(String[] args) {
        // Create a new instance of the Runnable implementation
        MyRunnable myRunnable = new MyRunnable();

        // Create a new thread and pass in the Runnable
        Thread thread = new Thread(myRunnable);

        // Start the thread
        thread.start();
    }

    private static class MyRunnable implements Runnable {
        @Override
        public void run() {
            // Do some work in the background
            System.out.println("Hello, World!");
        }
    }
}

When you run the above code , it will just print "Hello World" as there is nothing else inside the run() method. After this thread will come out of the run() method and it will be finished. 

Remember, the thread is started when you call the start() method, if you just call the run() method then the code inside run() will be executed in the current thread. That's also a key difference between start() and run() method of Thread class and something worth knowing. 


Also, Here is a nice summary of all the differences between Callable and Runnable in Java:

Runnable vs Callable in Java


That's all on the difference between Callable and Runnable interface in Java or difference between call() and run() method. Both are a very useful interface from core Java and a good understanding of where to use Runnable and Callable is a must for any good Java developer. In the next article, we will see an example of the Callable interface along with FutureTask to learn How to use the Callable interface in Java.


Other Java multi-threading questions for practice
Difference between start() and run() method of Thread class.
How to solve producer-consumer problem in Java using wait and notify
Why to wait and notify method are declared in Object class
Difference between CyclicBarrier and CountDownLatch in Java
Why to wait and notify method required to called from synchronized context


3 comments:

  1. What is the real use of Callable interface, I have never use it in production yet. to me Runnable seems to work always? I know that Callable can return value, throw Exception but I have to yet to found a convincing case to use it on production code. Can anyone who has some hands on experience suggest good examples of Callable in Java?

    ReplyDelete
    Replies
    1. Well the fact that method call() can return whatever type you want makes easy to trigger the execution of a method into a separate thread and return when the execution is over.
      For example, I have been using this pattern lately to run Groovy scripts into a Java application to handle specific behaviours for some of our customers. With running the custom script (written by third parties) into separate threads, I can better control their execution (i.e. stop them if they exceed a maximum duration). Combined with the java ScriptEngine framework, all I had to do is provide with an interface that Groovy scripts had to implement, and a little code to stick all this together.

      But honestly, the above article is a little poor as it doesn't provide much more information that the API javadoc.

      Delete
    2. Sir Mr Laurent Thomas i am new to this callable interface if you could share your experience with these interface then it would be better for us

      Delete

Feel free to comment, ask questions if you have any doubt.