Let’s break it down step by step:
🧠 Core Difference
| Concept | Thread | Runnable |
|---|---|---|
| What is it? | A class that represents a thread of execution | A functional interface (task to run in a thread) |
| Role | Executes the code | Defines the code to run |
| Relationship | Thread is both a task and the runner | Runnable is just the task; needs a thread to run it |
| Flexibility | ❌ Less flexible (extends Thread) | ✅ More flexible (can be reused/shared) |
| Usage | Thread t = new MyThread(); t.start(); | Thread t = new Thread(new MyRunnable()); t.start(); |
⚙️ Code Comparison
🔸 Using Thread (Extending the class)
class MyThread extends Thread {
public void run() {
System.out.println("Running in MyThread");
}
}
public class Main {
public static void main(String[] args) {
Thread t = new MyThread();
t.start();
}
}
🟡 Limit: Since Java supports only single inheritance, you can’t extend any other class.
🔹 Using Runnable (Implementing the interface)
class MyRunnable implements Runnable {
public void run() {
System.out.println("Running in MyRunnable");
}
}
public class Main {
public static void main(String[] args) {
Thread t = new Thread(new MyRunnable());
t.start();
}
}
🟢 Advantage:
- More flexible (you can still extend another class)
- Encouraged for clean design
- Works better with ExecutorService, thread pooling, and modern APIs
🔥 Bonus: With Lambdas (because Runnable is a functional interface)
Thread t = new Thread(() -> System.out.println("Running with lambda"));
t.start();
🧠 This is the modern, preferred way for short, simple tasks.
✅ Summary
| Feature | Thread | Runnable |
|---|---|---|
| Type | Class | Interface |
| Inheritance | Requires extending | Can be implemented with other classes |
| Flexibility | Less | More |
| Used With Executors | ❌ Awkward | ✅ Perfect fit |
| Preferred in modern code | ❌ Not really | ✅ Yes |