Future vs Callable vs Runnable — how do they relate? — Cracked Java
// Concurrency & Multithreading · Callable, Future & CompletableFuture
MidTheory

Future vs Callable vs Runnable — how do they relate?

They are three different roles: Runnable and Callable are the task you submit, while Future is the handle you get back to retrieve the task's eventual result.

Runnable vs Callable

Both wrap a unit of work, but they differ in return value and exceptions:

  • Runnable.run() returns void and cannot throw a checked exception.
  • Callable<V>.call() returns a V and may throw a checked exception.
Runnable r = () -> System.out.println("side effect only");

Callable<Integer> c = () -> {
    Thread.sleep(100);   // checked InterruptedException is allowed
    return 42;
};

Callable was added in Java 5 specifically because Runnable could not return a result or signal failure to the submitter — the work had to stash its result in a shared field, which is awkward and error-prone.

Where Future comes in

You hand a task to an ExecutorService. What you get back depends on what you submitted:

ExecutorService pool = Executors.newFixedThreadPool(2);

Future<Integer> f1 = pool.submit(c);        // Callable -> Future<Integer>
Future<?>       f2 = pool.submit(r);        // Runnable -> Future<?> (get() yields null)
Future<String>  f3 = pool.submit(r, "ok");  // Runnable + preset result

Integer result = f1.get();   // blocks until the Callable returns 42

Future<V> is the placeholder for a result computed asynchronously. Its contract is small: get() (blocking, optionally with timeout), isDone(), isCancelled(), and cancel().

The relationship in one line

Callable produces a value; Future delivers it. Runnable produces nothing, so its Future only tells you when it finished (or carries a result you preset).

Mark your status