Implement Runnable vs Extend Thread in Java

Last Updated : 11 Oct, 2025

In Java, multithreading allows multiple tasks to run concurrently, improving performance and resource utilization. There are two standard ways to create a thread:

1. Extending the Thread Class

  • A class directly inherits from the Thread class and overrides its run() method.
  • Each instance of this class represents a separate thread of execution
Java
class MyThread extends Thread{
    
    @Override
    public void run(){
        
        System.out.println("Thread is running");
    }
}

public class GFG{
    
    public static void main(String[] args){
        
        MyThread t1 = new MyThread();
        MyThread t2 = new MyThread();
        
        t1.start();  
        t2.start();  
    }
}

Output
Thread is running
Thread is running

2. Implementing the Runnable Interface

  • A class implements the Runnable interface and provides an implementation for the run() method.
  • A Runnable object is then passed to a Thread object when creating the thread.
Java
class MyRunnable implements Runnable{
    
    @Override
    public void run() {
        System.out.println("Thread is running");
    }
}

public class GFG{
    
    public static void main(String[] args){
        
        MyRunnable task = new MyRunnable();
        Thread t1 = new Thread(task);
        Thread t2 = new Thread(task);
        
        t1.start();  
        t2.start(); 
    }
}

Output
Thread is running
Thread is running

Key Differences Between Extending Thread and Implementing Runnable

1. Multiple Inheritance: Java does not support multiple inheritance for classes. If you extend Thread, your class cannot extend any other class. Implementing Runnable allows your class to extend another class while still enabling multithreading.

2. Resource Sharing: When implementing Runnable, a single Runnable object can be shared among multiple Thread objects, promoting better resource usage and reducing memory overhead. When extending Thread, each thread instance is a distinct object.

3. Separation of Concerns: Implementing Runnable promotes a cleaner separation between the task and the thread itself. The Runnable object defines what needs to be executed, while the Thread object handles how it is executed. Extending Thread combines the task and thread in a single class.

4. Flexibility with Executor Framework: The Runnable interface is compatible with Java's Executor framework, which provides a more advanced and flexible way to manage thread pools and task execution. Extending Thread cannot be used directly with these frameworks.


Comment