Runnable vs Callable Interview Questions and Answers
Master Runnable vs Callable with production-ready interview questions covering Runnable, Callable, Future, FutureTask, ExecutorService, exceptions, return values, thread pools, and enterprise use cases.
Runnable vs Callable Interview Questions & Answers
Introduction
One of the most common multithreading interview questions is:
"What is the difference between Runnable and Callable?"
Both are used to execute tasks concurrently, but they solve different problems.
In modern Java applications such as Spring Boot microservices, developers rarely create threads manually. Instead, they submit Runnable or Callable tasks to an ExecutorService.
Understanding their differences is essential for:
- Asynchronous programming
- Thread Pools
- Batch Processing
- Microservices
- Enterprise Java Development
1. What is Runnable?
Answer
Runnable is a functional interface used to execute a task concurrently.
It represents a task that:
- Performs work
- Does not return a result
- Cannot throw checked exceptions directly
Interface
@FunctionalInterface
public interface Runnable {
void run();
}
Example
Runnable task = () ->
System.out.println("Running");
new Thread(task).start();
2. What is Callable?
Answer
Callable is a functional interface introduced in Java 5.
Unlike Runnable, it:
- Returns a value
- Can throw checked exceptions
Interface
@FunctionalInterface
public interface Callable<V> {
V call() throws Exception;
}
Example
Callable<String> task =
() -> "Completed";
3. What is the difference between Runnable and Callable?
Answer
| Runnable | Callable |
|---|---|
| Introduced in Java 1.0 | Introduced in Java 5 |
run() method |
call() method |
| No return value | Returns a value |
| Cannot throw checked exceptions | Can throw checked exceptions |
Used with Thread and ExecutorService |
Used with ExecutorService |
Callable is generally preferred when a result is required.
4. What is Future?
Answer
A Future represents the result of an asynchronous computation.
Execution
Callable
↓
ExecutorService
↓
Future
↓
Result Available Later
Example
Future<Integer> future =
executor.submit(task);
The result can be retrieved later using get().
5. How do you retrieve the result from a Callable?
Answer
Example
ExecutorService executor =
Executors.newFixedThreadPool(2);
Callable<Integer> task =
() -> 100;
Future<Integer> future =
executor.submit(task);
Integer result =
future.get();
get() waits until the computation completes.
6. What is FutureTask?
Answer
FutureTask implements both:
- Runnable
- Future
Illustration
Callable
↓
FutureTask
↓
Runnable
↓
Thread
Example
Callable<String> task =
() -> "Done";
FutureTask<String> futureTask =
new FutureTask<>(task);
new Thread(futureTask).start();
String result = futureTask.get();
It acts as a bridge between Callable and Thread.
7. What is ExecutorService?
Answer
ExecutorService manages a pool of reusable threads.
Instead of creating threads manually,
Application
↓
ExecutorService
↓
Thread Pool
↓
Task Execution
Example
ExecutorService executor =
Executors.newFixedThreadPool(5);
Benefits
- Thread reuse
- Better performance
- Controlled concurrency
- Easier resource management
8. Can Runnable return a value?
Answer
No.
Example
Runnable task =
() -> {
System.out.println("Task");
};
If a result is needed, use:
- Callable
- Future
- CompletableFuture
instead of Runnable.
9. Can Runnable throw checked exceptions?
Answer
No.
Example
public void run() {
}
The run() method cannot declare checked exceptions.
Callable can.
public Integer call()
throws Exception {
}
10. When should you use Runnable and when should you use Callable?
Answer
Use Runnable when:
- No result is required.
- Fire-and-forget tasks.
- Logging
- Notifications
- Background cleanup
Use Callable when:
- A result is needed.
- Database queries
- API calls
- File processing
- Business calculations
11. Explain a production use case.
Answer
Scenario
An order processing service performs multiple independent tasks.
Order Request
│
┌──────┼──────────────┐
│ │ │
▼ ▼ ▼
Inventory Payment Invoice
Callable Callable Callable
│
▼
ExecutorService
│
▼
Future Results
│
▼
API Response
Benefits
- Parallel execution
- Better throughput
- Lower response time
This pattern is widely used in enterprise applications.
12. What are common mistakes related to Runnable and Callable?
Answer
Common mistakes include:
Creating raw threads instead of using ExecutorService.
Using Runnable when a result is required.
Ignoring Future.get() exceptions.
Forgetting to shut down the ExecutorService.
Blocking unnecessarily on Future.get().
Modern applications should use thread pools for better scalability.
13. What are the best practices?
Answer
Recommended practices
- Prefer
ExecutorServiceover manually creating threads. - Use
Callablewhen results are required. - Shut down executors gracefully.
executor.shutdown();
- Handle exceptions properly.
- Avoid blocking unnecessarily.
- Prefer
CompletableFuturefor complex asynchronous workflows. - Choose the appropriate thread pool size for the workload.
14. How does Callable compare with CompletableFuture?
Answer
| Callable | CompletableFuture |
|---|---|
| Single asynchronous task | Supports asynchronous pipelines |
Returns Future |
Returns CompletableFuture |
Blocking get() commonly used |
Supports non-blocking composition |
| Limited chaining | Rich chaining and combination APIs |
For modern asynchronous programming, CompletableFuture is generally preferred.
15. What interview tips should you remember?
Answer
Interviewers commonly ask:
- Runnable
- Callable
- Future
- FutureTask
- ExecutorService
- Runnable vs Callable
Future.get()- Checked exceptions
- Return values
- Production scenarios
Remember
- Runnable does not return a value.
- Callable returns a value.
- Callable can throw checked exceptions.
- Future represents asynchronous results.
- ExecutorService manages thread pools.
- FutureTask combines Runnable and Future.
- Prefer ExecutorService over manual thread creation.
- Use CompletableFuture for advanced asynchronous programming.
Summary
Runnable and Callable are the primary abstractions for concurrent task execution in Java. Runnable is suitable for fire-and-forget tasks, while Callable is designed for operations that return results or throw checked exceptions. Combined with ExecutorService and Future, they form the foundation of modern Java concurrency.
Key Takeaways
- Understand Runnable and Callable.
- Learn the differences between them.
- Know how Future works.
- Understand FutureTask.
- Learn ExecutorService fundamentals.
- Know when to use Runnable vs Callable.
- Understand production thread pool usage.
- Follow concurrency best practices.
- Support interview answers with enterprise examples.
- Build a strong foundation for Synchronization and Locks.