Runnable & Callable
About
Runnable and Callable are two interfaces in Java used for executing tasks in separate threads. Both are commonly used in multithreading and concurrency but have differences in functionality.
Runnable Interface
Definition
Runnableis an interface that represents a task to be executed by a thread.It has one method:
void run();It does not return a result and cannot throw checked exceptions.
Usage
A Runnable task can be executed by:
Creating a
ThreadobjectUsing
ExecutorService
Example 1: Implementing Runnable using a Class
Here, the run() method is executed in a separate thread.
Example 2: Using Runnable with ExecutorService
ExecutorService is a thread pool manager that efficiently manages threads.
Callable Interface
Definition
Callable<T>is a functional interface introduced in Java 5.Unlike
Runnable, it returns a result and can throw checked exceptions.It has one method:
The return type
Tallows it to be used for asynchronous computation.
Usage
A Callable task is executed using an ExecutorService and returns a Future<T> object.
Example 1: Implementing Callable with ExecutorService
Combining Runnable and Callable
If we want a Runnable but need a result, use Executors.callable(). This is useful when converting a Runnable to Callable.
Using FutureTask (Runnable + Callable)
If we need both Runnable and Callable behaviors, use FutureTask<T>.FutureTask allows combining Runnable execution with Callable result handling.
Comparison Runnable and Callable
Introduced in
Java 1.0
Java 5
Method
void run()
T call() throws Exception
Return Value
No (void)
Yes (Generic T)
Exception Handling
Cannot throw checked exceptions
Can throw checked exceptions
Used With
Thread, ExecutorService
ExecutorService, Future
Best For
Executing tasks without result
Executing tasks that return a value
When to Use Runnable vs Callable vs Others
Runnable vs Callable vs OthersUse Case
Use
Why?
You need to execute a task without returning a result
Runnable
Runnable.run() has a void return type, making it ideal for simple background tasks.
You need to execute a task and return a result
Callable
Callable.call() returns a value, allowing you to capture the task's output.
You need to execute a task but may need to check its completion later
Callable + Future
Future<T> allows retrieving the result later without blocking the main thread.
You need to execute a task and get notified when it's completed
FutureTask
FutureTask allows combining Runnable and Callable, and it can be used as a Future.
You need to execute multiple independent tasks and wait for all to complete
ExecutorService + invokeAll()
invokeAll() submits multiple Callabletasks and waits for all results.
You need to execute multiple independent tasks and get the first completed result
ExecutorService + invokeAny()
invokeAny() submits multiple Callabletasks and returns the first successful result.
You need fine-grained control over thread execution (e.g., priority, interruption)
Thread + Runnable
Thread can directly manage execution but is less flexible than thread pools.
You need to handle checked exceptions in a background task
Callable
Callable.call() supports throwing checked exceptions.
You need to execute a task repeatedly at a fixed rate
ScheduledExecutorService
scheduleAtFixedRate() and scheduleWithFixedDelay() allow scheduled execution.
You need to execute CPU-intensive parallel tasks
ForkJoinPool
ForkJoinPool supports work-stealing, ideal for recursive and parallel tasks.
You need to execute stream operations in parallel
Parallel Streams
stream().parallel() splits work across multiple cores automatically.
You need to process a collection of tasks asynchronously
CompletableFuture
CompletableFuture allows non-blocking execution and chaining tasks together.
You need to execute a task with a timeout
ExecutorService + Future.get(timeout)
Future.get(timeout, TimeUnit.SECONDS)prevents indefinite waiting.
You need to execute a task in the background and monitor progress
CompletableFuture + thenApply/thenAccept
CompletableFuture allows progress tracking and callbacks.
You need non-blocking, event-driven async execution
CompletableFuture + SupplyAsync()
Asynchronous execution without blocking threads.
Last updated