Skip to content

Commit 4cfd8a4

Browse files
committed
docs(concurrency): add detailed explanation of Runnable vs Callable in Java
WHAT was added: - Comprehensive documentation comparing Runnable and Callable. - Breakdown of: • Runnable: introduced in Java 1.0 (java.lang), no return, no checked exceptions. • Callable<V>: introduced in Java 1.5 (java.util.concurrent), returns a value, can throw checked exceptions. - Included code examples for both Runnable and Callable usage. - Added side-by-side comparison table (features, return type, exception handling, execution style). - Provided hybrid example using ExecutorService to demonstrate Runnable vs Callable execution. - Summarized real-world use cases for each: • Runnable → fire-and-forget tasks (logging, notifications, UI updates). • Callable → tasks with results (computations, API calls, DB queries). WHY this matters: - Clarifies the conceptual and practical differences between Runnable and Callable. - Provides a quick reference for when to use one over the other in concurrent programming. - Helps avoid common confusion for beginners transitioning from Runnable (classic) to Callable (modern). HINTS / NEXT STEPS: - Explore `FutureTask`, which can wrap both Runnable and Callable. - Demonstrate `invokeAll()` and `invokeAny()` with Callable for batch task handling. - Extend examples with exception handling in Callable and handling `ExecutionException`. KEYWORDS: java concurrency runnable callable future executorservice multithreading docs. Signed-off-by: https://github.com/Someshdiwan <[email protected]>
1 parent c028fce commit 4cfd8a4

File tree

1 file changed

+170
-0
lines changed

1 file changed

+170
-0
lines changed
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
# Runnable vs Callable in Java
2+
3+
In Java, both **Runnable** and **Callable** are interfaces used to represent tasks that can be executed by
4+
multiple threads (often with `ExecutorService`).
5+
6+
They provide a way to encapsulate a unit of work to be executed asynchronously, but they differ in functionality and design.
7+
8+
---
9+
10+
## 1. Runnable
11+
12+
- **Package**: `java.lang`
13+
- **Introduced in**: Java 1.0
14+
- **Signature**:
15+
```java
16+
@FunctionalInterface
17+
public interface Runnable {
18+
void run();
19+
}
20+
21+
Key Characteristics:
22+
Represents a task that does not return a result.
23+
Cannot throw a checked exception (only unchecked exceptions can be thrown).
24+
Typically used when you only need to execute some code concurrently, without returning a value.
25+
26+
Example:
27+
28+
class MyRunnable implements Runnable {
29+
@Override
30+
public void run() {
31+
System.out.println("Running task in thread: " + Thread.currentThread().getName());
32+
}
33+
}
34+
35+
public class RunnableExample {
36+
public static void main(String[] args) {
37+
Runnable task = new MyRunnable();
38+
Thread thread = new Thread(task);
39+
thread.start();
40+
}
41+
}
42+
43+
Output:
44+
45+
Running task in thread: Thread-0
46+
47+
48+
49+
50+
2. Callable
51+
Package: java.util.concurrent
52+
Introduced in: Java 1.5 (with the java.util.concurrent framework)
53+
Signature:
54+
55+
@FunctionalInterface
56+
public interface Callable<V> {
57+
V call() throws Exception;
58+
}
59+
60+
61+
62+
Key Characteristics:
63+
Represents a task that returns a result of type V.
64+
Can throw checked exceptions.
65+
Usually used with an ExecutorService where the result is obtained via a Future.
66+
67+
Example:
68+
69+
import java.util.concurrent.Callable;
70+
import java.util.concurrent.ExecutorService;
71+
import java.util.concurrent.Executors;
72+
import java.util.concurrent.Future;
73+
74+
class MyCallable implements Callable<Integer> {
75+
private int number;
76+
77+
public MyCallable(int number) {
78+
this.number = number;
79+
}
80+
81+
@Override
82+
public Integer call() throws Exception {
83+
int result = number * number;
84+
Thread.sleep(1000); // simulate computation
85+
return result;
86+
}
87+
}
88+
89+
public class CallableExample {
90+
public static void main(String[] args) throws Exception {
91+
ExecutorService executor = Executors.newSingleThreadExecutor();
92+
Callable<Integer> task = new MyCallable(5);
93+
94+
Future<Integer> future = executor.submit(task);
95+
96+
System.out.println("Result: " + future.get()); // waits for result
97+
executor.shutdown();
98+
}
99+
}
100+
101+
Output:
102+
103+
Result: 25
104+
105+
106+
107+
108+
3. Differences at a Glance
109+
110+
Feature Runnable Callable
111+
Package java.lang java.util.concurrent
112+
Return Type void Generic type V (returns a value)
113+
Exception Handling Cannot throw checked exceptions Can throw checked exceptions
114+
Introduced in Java 1.0 Java 1.5
115+
Suitable For Fire-and-forget tasks Tasks that return results or may throw exceptions
116+
Execution with Thread new Thread(runnable).start() Must be submitted to ExecutorService
117+
Integration with Future Not supported Returns a Future when submitted
118+
119+
120+
121+
122+
4. When to Use What?
123+
Use Runnable when:
124+
You just want to perform a task asynchronously without needing a result.
125+
Example: Logging, sending notifications, updating UI components, fire-and-forget tasks.
126+
Use Callable when:
127+
You want the task to return a value.
128+
You need to handle checked exceptions from within the task.
129+
Example: Complex computations, fetching data from an API, database queries.
130+
131+
132+
133+
5. Hybrid Example: Runnable vs Callable with ExecutorService
134+
135+
import java.util.concurrent.*;
136+
137+
public class RunnableVsCallable {
138+
public static void main(String[] args) throws Exception {
139+
ExecutorService executor = Executors.newFixedThreadPool(2);
140+
141+
// Runnable task
142+
Runnable runnableTask = () -> System.out.println("Runnable running...");
143+
executor.submit(runnableTask);
144+
145+
// Callable task
146+
Callable<String> callableTask = () -> {
147+
Thread.sleep(500);
148+
return "Callable result";
149+
};
150+
151+
Future<String> result = executor.submit(callableTask);
152+
System.out.println("Callable says: " + result.get());
153+
154+
executor.shutdown();
155+
}
156+
}
157+
158+
Output:
159+
160+
Runnable running...
161+
Callable says: Callable result
162+
163+
164+
165+
6. Summary
166+
Runnable is simple and lightweight, used for tasks that don’t need to return anything.
167+
Callable is more powerful, introduced with the concurrency framework, used for tasks that need to return a result or handle checked exceptions.
168+
Both are essential building blocks of concurrent programming in Java, and the choice depends on the type of task you want to execute.
169+
170+
---

0 commit comments

Comments
 (0)