Runnable vs Callable in Java

1. Introduction

In Java, Runnable and Callable are two interfaces that are used with threading and task execution. Runnable has been part of Java since version 1.0, and it represents a task that can be run by a thread. Callable was introduced in Java 5 and is similar to Runnable but it can return a result and throw a checked exception.

2. Key Points

1. Runnable tasks do not return a result.

2. Callable tasks can return a result and can also throw checked exceptions.

3. Runnable has a run() method that does not return a value nor throw exceptions.

4. Callable has a call() method that returns a value and can throw an exception.

5. Runnable is typically used with threads, while Callable is used with ExecutorService which can return Future objects.

3. Differences

Runnable Callable
Has a run() method that returns void. Has a call() method that returns a value and can throw exceptions.
Cannot throw checked exceptions. Can throw checked exceptions.
Good for general use in threads when no result is needed. Good for tasks that require a result or when you need to handle exceptions.

4. Example

import java.util.concurrent.*;

public class RunnableVsCallable {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // Using Runnable
        Runnable runnableTask = () -> {
            // Task implementation here
            System.out.println("Running runnable task");
        Thread runnableThread = new Thread(runnableTask);

        // Using Callable
        Callable<String> callableTask = () -> {
            // Task implementation here
            return "Result from callable";
        ExecutorService executorService = Executors.newFixedThreadPool(1);
        Future<String> future = executorService.submit(callableTask);

        // Print result of callable

        // Shutdown the executor service


Running runnable task
Result from callable


1. The runnableTask implements Runnable and prints a message; it cannot return a result.

2. The callableTask implements Callable and returns a string; it can also throw exceptions.

3. future.get() is used to retrieve the result from the callableTask.

4. The executor service needs to be shut down explicitly after its use.

5. When to use?

- Use Runnable when you want to run code in a thread and you don't need to return a result or throw a checked exception.

- Use Callable when you need to return a result from your task or when your task might throw a checked exception and you want to handle it.