| Runnable | Callable |
| Defines a task that can be executed by a thread | Similar to Runnable, but it is intended to yield a value. |
Contains one method run() which holds the logic that will be executed by the thread | Contains one method call() which holds the logic that will be executed by the thread. |
| Can throw checked exceptions. | |
| Returns a value which can be used for further processing. | |
| Can be used to check the status of the task, wait for it to complete and retrieve the result of the task. | |
| Allows cancellation of the task if it is not finished yet. | |
| Both Runnable and Callable interfaces can be utilised to generate and launch threads in a Java program. |
Runnable Example
class RunnableTask implements Runnable {
public void run() {
System.out.println("Running Runnable Task");
}
}
public class Main {
public static void main(String[] args) {
RunnableTask task = new RunnableTask();
Thread thread = new Thread(task);
thread.start();
}
}
This will output “Running Runnable Task”.
Callable Example
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
class CallableTask implements Callable<String> {
public String call() throws Exception {
System.out.println("Running Callable Task");
return "Task Complete";
}
}
public class Main {
public static void main(String[] args) {
CallableTask task = new CallableTask();
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(task);
try {
System.out.println(future.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
executor.shutdown();
}
}
This will output “Running Callable Task” and “Task Complete” when the program is executed.
- The
CallableTaskclass implements theCallableinterface and overrides thecall()method. - The return type of
call()method isString. - The
submit()method ofExecutorServiceis used to submit the task for execution and it returns an object ofFuturerepresenting the result of the task. - And the
get()method is used to retrieve the result of the task.
Final Note – How to choose between Runnable and Callable?
Generally, if you need to perform a computation that returns a value, throws checked exceptions, or requires extra control over the execution of the thread, it’s optimal to use the Callable interface. Conversely, if you just need to run a basic task in a separate thread, the Runnable interface is perhaps the prime choice.
📚 Further Reading & Related Topics
If you’re exploring the difference between Runnable and Callable interfaces in Java, these related articles will provide deeper insights:
• Threads in Java: The Difference Between Calling Start and Run Methods – Learn about thread management and how Runnable and Callable integrate with thread execution in Java.
• Java 16 and the Standardization of Records: Simplifying Data Classes – Explore how modern Java features like records and functional programming complement the usage of concurrency utilities such as Runnable and Callable.









Leave a comment