The difference between the Runnable and Callable interfaces in Java
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
In Java, concurrency is a powerful feature that allows the execution of multiple threads simultaneously, enhancing performance especially in application environments where multiple tasks need to be executed concurrently or where operations are blocking in nature. To facilitate concurrency, Java provides several mechanisms, one of which involves using interfaces to encapsulate tasks that are executed by threads. The two primary interfaces provided by Java for such purposes are Runnable and Callable.
Understanding Runnable
Runnable is one of the oldest interfaces in Java, introduced in Java 1.0. It is found in the java.lang package. The Runnable interface is designed to encapsulate a unit of executable code which can be executed by a thread. It has a single method called run() that does not accept any arguments and does not return any value (void return type):
Understanding Callable
Callable, introduced later in Java 1.5, is a more versatile and advanced counterpart to Runnable. It belongs to the java.util.concurrent package, which contains many of the enhancements for concurrency introduced in Java 1.5. Unlike Runnable, the Callable interface is generic and its single method call() returns a value and is able to throw an exception:
The return type V represents the type of value that the Callable task returns after its execution.
Key Differences
- Return Value:
- Runnable: The
run()method does not return any value. - Callable: The
call()method returns a value, the type of which can be defined as per the requirements.
- Exception Handling:
- Runnable: The
run()method cannot throw any checked exceptions; it can only handle exceptions internally or throw unchecked exceptions. - Callable: The
call()method can throw checked exceptions, allowing the callers to handle them.
- Usage with Executor Services:
- Runnable: When submitted to an executor service, no value can be obtained directly from the
Runnableafter its execution. - Callable: When a
Callableis submitted to an executor service, it returns aFutureobject, which can be used to retrieve the result of theCallable’scall()method asynchronously.
Here is a summary table of their differences:
| Feature | Runnable | Callable |
| Return type | void | Generic type V |
| Exception | No checked exceptions allowed | Can throw checked exceptions |
| Result retrieval | None directly from Runnable | Via Future from executor service |
Practical Scenarios
- Runnable: Ideal for simple concurrency tasks, especially for fire-and-forget operations where no result is needed post execution, such as periodic cleanup tasks or triggers in a web server.
- Callable: Suitable for tasks requiring computation that needs to return a result or status, such as processing a large data set and returning a computed result, or where operations may throw exceptions that need to be managed, such as when interacting with I/O operations.
Examples
Runnable Example:
Callable Example:
Conclusion
Choosing between Runnable and Callable typically depends on the requirements of the concurrency tasks within a Java application. If you need straightforward execution and do not require any results back from the thread, Runnable is adequate. However, for more complex needs where results, generic types, and exception handling are involved, Callable is the optimal choice. With the introduction of lambdas and enhanced concurrency utilities in recent versions of Java, implementing these interfaces has become more straightforward and powerful.
Related reading
- The difference between the Runnable and Callable interfaces in Java
- The pipe 'async' could not be found
- The right way to limit maximum number of threads running at once?
- The thread has exited with code 0 0x0 with no unhandled exception
- The JPA hashCode() / equals() dilemma
- The performance impact of using instanceof in Java
- The web application appears to have started a thread named Timer-0 but has failed to stop it
- There is a pending asynchronous operation, and only one asynchronous operation can be pending concurrently

OOD Fundamentals
Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.