Callable vs Future in Java

Last Updated : 9 Apr, 2026

In Java, multithreading allows tasks to run concurrently, improving performance and responsiveness. Traditionally, developers used the Runnable interface to define tasks, but it has two major limitations: it cannot return a result and cannot throw checked exceptions. To overcome these, Java introduced the Callable and Future interfaces in Java 5.

  • Callable executes a task and returns a result with exception handling
  • Future represents the result of a Callable task and retrieves it later

Callable Interface

The Callable interface represents a task that returns a result and may throw an exception. It is similar to Runnable, but more flexible since it can return a value and throw checked exceptions.

  • Executes a task and returns a result using the call() method
  • Can throw checked exceptions during execution
Java
import java.util.concurrent.*;

public class CallableExample {
    public static void main(String[] args) throws Exception {
        ExecutorService executor = Executors.newSingleThreadExecutor();

        Callable<Integer> task = () -> {
            int sum = 0;
            for (int i = 1; i <= 5; i++) sum += i;
            return sum;  // returns result
        };

        Future<Integer> future = executor.submit(task);

        System.out.println("Result: " + future.get()); 
        executor.shutdown();
    }
}

Output
Result: 15

Explanation: A Callable task is submitted to the executor. It calculates the sum of numbers from 1 to 5 and returns the result. The result is retrieved using future.get() after the task finishes.

Future Interface

The Future interface represents the result of an asynchronous computation. When you submit a Callable or Runnable task to an ExecutorService, it returns a Future object.

  • Stores the result of an asynchronous computation
  • Provides methods like get() to retrieve the result and isDone() to check completion
Java
import java.util.concurrent.*;

public class CallableFutureExample {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newSingleThreadExecutor();

        Future<Integer> future = executor.submit(() -> 10 + 20);

        try {
            Integer result = future.get(); // waits but returns instantly
            System.out.println("Result: " + result);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            executor.shutdown();
        }
    }
}

Output
Result: 30

Explanation: This code creates a single-thread executor to run a task asynchronously using Callable. The task calculates the sum of 10 and 20, and the result is stored in a Future object. Using future.get(), the program retrieves the result (30), and finally shuts down the executor to free resources.

Callable vs Future

Table showing difference between callable and future.

FeatureCallableFuture
PurposeRepresents a task that returns a resultRepresents the result of an asynchronous task
Return TypeReturns a result when executedHolds the result returned by a Callable
Defined Injava.util.concurrent packagejava.util.concurrent package
ExecutionSubmitted to ExecutorServiceReturned by ExecutorService.submit()
MethodsHas one method call()Has methods like get(), isDone(), cancel()
Exception HandlingCan throw checked exceptionsHandles results and exceptions after execution
UsageDefines what to executeControls, monitors, and retrieves the result of a task
Comment