In Java, there are two ways to create threads i.e. implementing Runnable interface and extending Thread class. In this Java concurrency tutorial, we will identify the differences between both ways i.e. extends thread Vs. implements runnable.
In general, until we have a particular reason, it is always recommended to implement the Runnable interface to create new threads. This way, the child class is free to extend another class, if needed.
We should extend the Thread class only if we want to override or extend the behavior of the Thread class itself, and it is not recommended at all.
1. Thread Class
The Thread class represents a thread of execution in a Java program. We extend the Thread class in a child class and override the run() method.
public class MyThread extends Thread {
@Override
public void run() {
System.out.println("Thread is running");
}
}
To run the thread, we call its start() method.
MyThread thread = new MyThread();
thread.start();
The Thread class itself implements the Runnable interface.
2. Runnable Interface
A class should implement the Runnable interface if instances are intended to be executed by a thread. The code to be executed is written in the run() method.
public class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("Runnable is running");
}
}
To run the runnable code, we create a new Thread object and pass the runnable as a constructor argument. After this, we can use the Thread.start() method to run the executable code.
MyRunnable runnable = new MyRunnable();
Thread thread = new Thread(runnable);
thread.start();
3. Difference between Runnable vs. Thread
There has been a good amount of debate on which is the better way. I also tried to find out, and below is my learning.
| Feature | Runnable | Thread |
|---|---|---|
| Implementation | This is an Interface | This is a Class |
| Inheritance | The child class can extend another class | The child class cannot extend another class |
| Code Reusability | A single instance can be shared among multiple threads | Each thread needs a new instance |
| Resource Sharing | Allows sharing of resources among multiple threads | More difficult to share resources |
| Memory Overhead | Lower memory overhead as no separate object is created for the thread | Higher memory overhead as each thread object has its own memory |
Implementing Runnable makes your class more flexible. If you extend Thread then the action you’re doing is always going to be in a thread. However, if you implement Runnable it doesn’t have to be. You can run it in a thread, pass it to some kind of executor service, or just pass it around as a task within a single-threaded application.
4. Conclusion
Implementing Runnable is the preferred way to do it. Here, you’re not specializing or modifying the thread’s behavior. You’re just giving the thread something to run. That means composition is the better way to go.
That’s all about the differences between Runnable interface and Thread class in Java. If you know something more, please put that in the comments section and I will include it in the post content.
Happy Learning !!
its nice but needed more clarification or explanation
Is there any specific question or explanation needed?
At point 4, how can a task(non-run metho) inside Thread extending class, still need to run in thread only. It can still be executed within a main thread. Could u pls elaborate?
Thread creating using Runable is bettter in terms of lamda expression and Functional interface
By implementing Runnable interface, we can only override the run() method. But when we extend Thread class, we can use many methods based on our requirements. If we want to make our class as a thread, we can always go for extending the Thread class rather than implementing Runnable interface.
Hello Sowmya rajan,
As per my understanding, Thread is a curse in java. If you create multiple threads then there would be a chance of memory overhead and hence the performance of the app will go down.
why we extends a thread class and what are the advantage of it
Well Explained. Thanks to Lokesh !
Good points on topic
Thanks lokesh..
As per my knowledge, the advantage is – when there are multiple threads then, memory usage would be more in case of extends Thread. Because, each of your threads contains unique object associated with it. Where as, memory usage would be less in case of implements Runnable. Because, many threads can share the same runnable instance.
You are right Gopi. Point 5 state the same thought as you. Key thing is that it “CAN” share (as you also said); not always.
Awesome explanation !!
Small correction in point 4
It should be ” implements Runnable” Not “extend Runnable”
i want what the main difference in the thread & and Runnable interface?
5) By extending Thread, each of your threads has a unique object associated with it, whereas implementing Runnable, many threads can share the same runnable instance. – This statement seems wrong to me.
Many threads can share the same Thread object, same as Runnable instance.
For example,
public class A1 implements Runnable {….}
public class B1 extends Thread {….}
public class ABMain {
public static void main( String[] args ) {
A1 a = new A1(); //Create runnable instance
B1 b = new B1(); // Create Thread instance
new Thread( a ).start(); //Starts runnable instance
new Thread( b ).start(); //Starts Thread instance.
new Thread( a ).start(); // 2nd thread sharing same runnable instance A1
new Thread( b ).start(); // 2nd thread sharing same Thread instance.
}
}
Difference between Thread and Runnable I found is, Thread class provides apis to configure Thread instance based on your need.
If you extends Thread class, then
1. you will have flexibility to set priority to Thread instance,
2. you can create daemon thread,
3. you can check if thread is terminated, alive etc.
There are apis available in Thread class which is not avaialbe in Runnable. Those apis helps developers to configure Thread properties.
I modified your program a little bit, to correct the picture of usage of thread and runnable.
class A1 implements Runnable {private int counter = 0;
@Override
public void run() {
counter++;
System.out.println("Running A1 -> " + counter);
}
}
class B1 extends Thread {
private int counter = 0;
@Override
public void run() {
counter++;
System.out.println("Running B1 -> " + counter);
}
}
public class ABMain {
public static void main(String[] args) throws InterruptedException {
A1 a = new A1(); // Create runnable instance
B1 b = new B1(); // Create Thread instance
new Thread(a).start();
Thread.sleep(1000);
new Thread(a).start();
Thread.sleep(1000);
new Thread(a).start();
Thread.sleep(1000);
new B1().start();
Thread.sleep(1000);
new B1().start();
Thread.sleep(1000);
new B1().start();
}
}
Output:
1
2
3
1
1
1
1) A1 a = new A1(); does not make a thread. It’s just another class with no extra behavior. If you call A1.run() then it is not new thread. And A1.start() is not available to this class.
2) Only way to create start a thread in java is calling it’s start method.
3) If you look at constructor of Thread class, no constructor takes parameter of Thread class itself. And we know that Thread implements Runnable, effectively any call such as “new Thread(a).start();” is starting a thread with runnable mechanism.
4) Correct way to start thread (“using extend”) is calling it’s start method only directly.
e.g. new B1().start();
5) So effectively, in both techniques in your code, you are doing the same thing i.e. implementing runnable.
It’s correct post.
By extending Thread, each of your threads has a unique object associated with it, whereas implementing Runnable, many threads can share the same runnable instance.
The statement is alright but what is the advantage we gain here ?
The code is misleading. It doesn’t match the intent. It’s true that
Threadclass itself implementsRunnableinterface, so any instance of a class extending theThreadclass can be passed in to creating new thread.These two threads share the same instance.
You have a point. Removing the statement from above post this until I find a reason to include.