What are the 2 ways of multithreading in Java?
In Java, there are two primary ways to implement multithreading:
1. Extending the Thread
Class
This is the simpler approach where you directly extend the Thread
class and override its run()
method. This is useful when you need to define a specific thread behavior by overriding the run()
method.
Steps:
- Create a class that extends
Thread
. - Override the
run()
method to define the task that the thread should perform. - Create an instance of the class and call its
start()
method to initiate the thread.
Example:
class MyThread extends Thread { public void run() { System.out.println("Thread is running: " + Thread.currentThread().getName()); } } public class Main { public static void main(String[] args) { MyThread thread1 = new MyThread(); thread1.start(); // Start the thread MyThread thread2 = new MyThread(); thread2.start(); // Start another thread } }
In this approach:
- The
run()
method contains the code that will be executed by the thread. - The
start()
method initiates the thread's execution, which calls therun()
method.
2. Implementing the Runnable
Interface
In this approach, instead of extending the Thread
class, you implement the Runnable
interface, which defines a run()
method. This approach is preferred because it allows a class to extend another class while still being able to implement the Runnable
interface. The Runnable
interface separates the task from the thread, allowing better flexibility and code reuse.
Steps:
- Create a class that implements the
Runnable
interface. - Implement the
run()
method to define the task. - Pass the
Runnable
instance to aThread
object and call itsstart()
method to initiate the thread.
Example:
class MyRunnable implements Runnable { public void run() { System.out.println("Runnable thread is running: " + Thread.currentThread().getName()); } } public class Main { public static void main(String[] args) { MyRunnable task = new MyRunnable(); Thread thread1 = new Thread(task); // Pass the Runnable to a Thread thread1.start(); // Start the thread Thread thread2 = new Thread(task); thread2.start(); // Start another thread } }
In this approach:
- The
run()
method in theRunnable
interface defines the task to be executed. - You create a
Thread
object by passing theRunnable
implementation to it, and then callstart()
to begin execution.
Comparison Between the Two Approaches
Feature | Extending the Thread Class | Implementing the Runnable Interface |
---|---|---|
Inheritance | Can only extend Thread , limiting other class extensions. | Can implement Runnable and still extend another class. |
Flexibility | Less flexible, as Java supports single inheritance. | More flexible, as a class can implement multiple interfaces. |
Multiple Threads | Each thread is tied to a specific class that extends Thread . | The same Runnable object can be passed to multiple threads. |
Code Reusability | Less reusable because of inheritance. | More reusable, as the same Runnable can be used in different threads. |
Resource Sharing | Threads share resources within the Thread class. | Runnable can be shared between multiple threads, allowing for better resource management. |
Conclusion
- Extending the
Thread
class is simpler and works well when you don't need to inherit from other classes. - Implementing the
Runnable
interface is the preferred and more flexible approach, especially when you need to implement multiple interfaces or manage resources shared across threads.
Recommended Courses
To deepen your understanding of multithreading in Java and prepare for coding interviews, consider exploring these courses from DesignGurus.io:
- Grokking Multithreading and Concurrency for Coding Interviews
- Grokking Data Structures & Algorithms for Coding Interviews
- Grokking the System Design Interview
These courses will help you build a solid foundation in multithreading and concurrency, preparing you for real-world applications and technical interviews.
GET YOUR FREE
Coding Questions Catalog