Saturday, March 9, 2024

Java Thread class and Runnable interface

 Choosing between extending the `Thread` class and implementing the `Runnable` interface in Java depends on various factors related to code design, flexibility, and the intended use of the threading mechanism. Here are some considerations to help you decide:

Extending `Thread` Class

Simplicity

   - Extending the `Thread` class can be simpler and more concise, especially for small, self-contained tasks.

    class MyThread extends Thread {

        public void run() {

            // Code to be executed in the thread

            System.out.println("Thread running");

        }

    }

    // Creating and starting a thread

    MyThread myThread = new MyThread();

    myThread.start();

    

Direct Access to Thread Methods:

   - When you extend the `Thread` class, you have direct access to various thread-related methods, such as `start()`, `sleep()`, `interrupt()`, etc.


    myThread.interrupt(); // Example of using a method directly

Single Inheritance Limitation:

   - If you need your class to extend another class, using the `Thread` class directly might be more convenient, as Java supports single inheritance.

Implementing `Runnable` Interface:

Flexibility in Inheritance:

   - Implementing the `Runnable` interface allows your class to extend another class, providing more flexibility in designing your class hierarchy.


    class MyBaseClass {}


    class MyRunnable extends MyBaseClass implements Runnable {

        public void run() {

            // Code to be executed in the thread

            System.out.println("Thread running");

        }

    }

Encourages Composition:

   - Implementing `Runnable` promotes a more object-oriented design by encouraging composition over inheritance. You can create multiple instances of your `Runnable` class and pass them to different threads.

    Runnable myRunnable = new MyRunnable();

    Thread thread1 = new Thread(myRunnable);

    Thread thread2 = new Thread(myRunnable);

Better Separation of Concerns:

   - Separating the task (defined in the `run` method) from the thread itself allows for better separation of concerns and more flexibility in managing and reusing code.


    class MyRunnable implements Runnable {

        public void run() {

            // Code to be executed in the thread

            System.out.println("Thread running");

        }

    }

  

    // Creating and starting a thread

    Runnable myRunnable = new MyRunnable();

    Thread thread = new Thread(myRunnable);

    thread.start();

Resource Sharing:

   - Implementing `Runnable` is often preferred when multiple threads need to share the same instance of a task, allowing for better control over resource sharing.

General Guideline

Use `Runnable` for Task, `Thread` for Control:

  - A common guideline is to use `Runnable` for representing the task or work that the thread performs and use `Thread` for controlling the execution of the thread itself.

Prefer Composition over Inheritance:

  - Favor composition over inheritance to achieve a more flexible and maintainable code. Implementing `Runnable` allows you to compose tasks independently of the thread control mechanism.

Consider the Single Responsibility Principle (SRP):

  - Follow the Single Responsibility Principle, which suggests that a class should have only one reason to change. `Runnable` Separating the task from the thread itself supports this principle.

In summary, both approaches have their use cases. 

  • If you have a small, standalone task, extending the `Thread` class might be more straightforward. 
  • If you need more flexibility in class hierarchy, better separation of concerns, or the ability to share tasks among multiple threads, implementing the `Runnable` interface is often preferred.
  • It's also worth noting that the Executor framework, introduced in the `java.util.concurrent` package, is a powerful alternative that allows for even more flexible thread management without directly dealing with `Thread` or `Runnable` instances.

No comments:

Post a Comment

LeetCode C++ Cheat Sheet June

🎯 Core Patterns & Representative Questions 1. Arrays & Hashing Two Sum – hash map → O(n) Contains Duplicate , Product of A...