Creating Threads in Java
There are two primary ways to create a thread in Java:
- By extending the
Threadclass. - By implementing the
Runnableinterface.
Both methods have their use cases, but implementing the Runnable interface is generally preferred.
1. By Extending the Thread Class
To create a thread using the Thread class, you need to:
- Create a class that extends the
java.lang.Threadclass. - Override the
run()method. This method contains the code that will be executed by the thread. - Create an object of your class and call the
start()method to begin execution.
Example: Extending Thread
class LabThread1 extends Thread {
// Overriding the run method
public void run() {
System.out.println("Thread is running via Thread class!");
}
public static void main(String args[]) {
// Creating an object of our custom thread class
LabThread1 t1 = new LabThread1();
// Calling start() to spawn the thread and execute run()
t1.start();
}
}
[!WARNING] Never call the
run()method directly. Callingrun()directly will execute the code sequentially in the current thread (the main thread) rather than spawning a new thread. Always usestart().
2. By Implementing the Runnable Interface
To create a thread using the Runnable interface, you need to:
- Create a class that implements the
java.lang.Runnableinterface. - Provide the implementation for the
run()method. - Pass an instance of your class to a
Threadobject's constructor. - Call the
start()method on theThreadobject.
Example: Implementing Runnable
class LabThread2 implements Runnable {
// Providing implementation for the run method
public void run() {
System.out.println("Thread is running via Runnable interface!");
}
public static void main(String args[]) {
// 1. Create an instance of the class
LabThread2 m1 = new LabThread2();
// 2. Pass it to a Thread object
Thread t1 = new Thread(m1);
// 3. Call start()
t1.start();
}
}
Which approach is better?
Implementing the Runnable interface is generally considered the better approach for the following reasons:
| Feature | Extending Thread Class | Implementing Runnable Interface |
|---|---|---|
| Multiple Inheritance | Java does not support multiple inheritance. If you extend Thread, your class cannot extend any other class. | Since Runnable is an interface, your class can implement Runnable and still extend another class. |
| Object Orientation | Extending Thread means your class is a Thread, which may not be logically accurate if your class just needs to run some task. | Implementing Runnable separates the task (the run method) from the runner (the Thread), adhering better to OOP principles. |
| Resource Sharing | Harder to share resources across multiple threads. | Easier to share resources because you can pass the same Runnable instance to multiple Thread objects. |
[!TIP] From Java 8 onwards, because
Runnableis a Functional Interface (it has only one abstract method,run()), you can create and start threads elegantly using Lambda Expressions:
public class LabThread3 {
public static void main(String args[]) {
// Using Lambda Expression for Runnable
Thread t1 = new Thread(() -> {
System.out.println("Thread is running via Lambda Expression!");
});
t1.start();
}
}