Creating Threads

⭐ Interview Importance: MEDIUM
⏱️ Revision Time: 5 min

TL;DR

In Java, there are two fundamental ways to create a thread:

  1. Extend the Thread class and override the run() method.
  2. Implement the Runnable interface and pass it to a Thread constructor (Highly Recommended).

Concept

When Java was first created, they offered two options for thread creation.

Method 1: Extending Thread (The Old Way)

You create a class that inherits from java.lang.Thread. You override the run() method with your logic. Because Java does not support multiple inheritance, this means your class can never extend any other class. It is locked into being just a Thread.

Method 2: Implementing Runnable (The Modern Way)

You create a class that implements the Runnable interface. This interface only requires one method: run(). You pass an instance of this class to a raw Thread object. Because it’s an interface, your class is free to extend other classes (like extends Player). Furthermore, with Java 8, Runnable is a Functional Interface, meaning you can just pass a Lambda Expression instead of writing a whole class.

Examples

// --- METHOD 1: Extending Thread ---
class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("Running via Extended Thread");
    }
}

// --- METHOD 2: Implementing Runnable ---
class MyRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("Running via Runnable Interface");
    }
}

public class CreateThreadsExample {
    public static void main(String[] args) {
        
        // Executing Method 1
        MyThread t1 = new MyThread();
        t1.start();
        
        // Executing Method 2
        Thread t2 = new Thread(new MyRunnable());
        t2.start();
        
        // Executing Method 2 (Java 8 Lambda Style - BEST PRACTICE)
        Thread t3 = new Thread(() -> {
            System.out.println("Running via Lambda");
        });
        t3.start();
    }
}

Interview Questions

Q: Why is implementing Runnable considered better than extending Thread?
A: 1. Inheritance Limits: Java only allows single inheritance. If you extend Thread, your class cannot extend any other parent class.
2. Separation of Concerns: A Thread object represents the OS execution mechanism (the engine). A Runnable object represents the task to be executed (the payload). It is better software design to separate the task logic from the execution engine.
3. Thread Pools: Modern Java relies heavily on ExecutorService (Thread Pools). Thread pools do not accept subclasses of Thread; they are specifically designed to execute Runnable (or Callable) payloads.