What Is the Difference Between Callable and Runnable in Java?

What Is the Difference Between Callable and Runnable in Java?

In Java, when working with threads and concurrency, two common interfaces are Runnable and Callable. While they both allow tasks to be executed asynchronously, they have some key differences. This article will explain what these interfaces are, how they differ, and provide code examples to help you understand their use cases. Whether you’re a beginner or an advanced Java developer, this guide will give you a clear understanding of these interfaces.

Introduction to Runnable

The Runnable interface is the simplest way to define tasks that will be executed by multiple threads. It represents a task that can be executed asynchronously, and its main method is run(), which contains the code to be executed by the thread. The Runnable interface does not return any result or throw any exception.

Example of Runnable

class MyRunnable implements Runnable {
    public void run() {
        System.out.println("Runnable Task is running in thread: " + Thread.currentThread().getName());
    }

    public static void main(String[] args) {
        MyRunnable task = new MyRunnable();
        Thread thread = new Thread(task);
        thread.start();
    }
}
    

In the above example, a Runnable task is created and executed using a new Thread. The run() method contains the task logic that will be executed by the thread when it starts. Since Runnable doesn’t return any result, it is primarily used when the result is not needed.

Introduction to Callable

The Callable interface, on the other hand, is an extension of the Runnable interface, introduced in Java 5, and it represents a task that can return a result or throw an exception. Unlike Runnable, which doesn’t return any value, Callable allows you to return a result or handle exceptions, which makes it more flexible.

Example of Callable

import java.util.concurrent.*;

class MyCallable implements Callable {
    public Integer call() throws Exception {
        System.out.println("Callable Task is running in thread: " + Thread.currentThread().getName());
        return 123; // Return some value
    }

    public static void main(String[] args) throws Exception {
        MyCallable task = new MyCallable();
        ExecutorService executor = Executors.newSingleThreadExecutor();
        Future future = executor.submit(task);
        Integer result = future.get(); // Get the result from the Callable task
        System.out.println("Result from Callable: " + result);
        executor.shutdown();
    }
}
    

In this example, MyCallable implements Callable, which means it will return an Integer value. The result can be accessed using the Future object, which represents the result of an asynchronous computation. The future.get() method is used to retrieve the result once the task is completed.

Key Differences Between Callable and Runnable

Aspect Runnable Callable
Return Type No return value (void) Can return a result (any object)
Exception Handling Cannot throw checked exceptions Can throw checked exceptions
Execution Mechanism Used with Thread class Used with ExecutorService
Task Submission Passed to a Thread object Passed to an ExecutorService using submit()

When to Use Runnable vs Callable?

You should choose Runnable when:

  • You don’t need to return any result from the task.
  • The task doesn’t throw any checked exceptions.
  • Performance is a priority and exception handling is not required.

You should choose Callable when:

  • You need to return a result from the task.
  • The task might throw checked exceptions that need to be handled.
  • You are working with an ExecutorService and need to retrieve the result of the task asynchronously.

Conclusion

In summary, both Runnable and Callable interfaces are useful for executing tasks asynchronously, but they cater to different requirements. Use Runnable when you don’t need to return a result and when handling exceptions is not a concern. On the other hand, use Callable when you need to return a result or handle exceptions, especially in multithreaded environments managed by an ExecutorService.

Now that you understand the difference between Runnable and Callable, you can decide which one to use based on the task requirements in your Java applications.

© 2025 Java Tutorials. All Rights Reserved.

Please follow and like us:

Leave a Comment