Showing posts with label Java Thread. Show all posts
Showing posts with label Java Thread. Show all posts

Friday, June 23, 2023

Difference between Process and Thread in Java - Example

In Java, a process and a thread are both units of execution, but they differ in their characteristics and functionality. Let's explore the difference between a process and a thread with an example:

Process:

A process can be thought of as an instance of a running program. It has its own memory space and resources. Each process runs independently and does not directly share memory with other processes. Processes are managed by the operating system, and inter-process communication (IPC) mechanisms like pipes or sockets are typically used for communication between processes.

Example: Consider a scenario where you have a text editor application and a web browser application running simultaneously on your computer. These two applications are separate processes. If one of them crashes, it does not affect the other process.

Thread:

A thread is a lightweight unit of execution within a process. Multiple threads can exist within a single process, and they share the same memory space and resources of that process. Threads are used to achieve parallelism or concurrent execution within a program. They allow multiple tasks to be executed concurrently, enhancing performance and responsiveness.

Example: Imagine a music player application where you have a user interface that displays the current song information and a background thread that continuously buffers and plays the audio. The user interface and audio playback are separate threads within the same process. The user can interact with the interface while the audio plays uninterrupted.


Key Differences:


Memory and Resources: Each process has its own memory space and resources, while threads share the same memory and resources within a process.

Communication: Processes typically use IPC mechanisms for communication, while threads communicate through shared memory within a process.

Independence: Processes are independent entities, and one process crashing does not affect others. Threads within a process are interdependent, and issues in one thread can impact the entire process.

Creation Overhead: Creating a new process is more resource-intensive as it requires duplicating the entire process, including its memory space. Creating a thread is relatively lightweight and has less overhead.

Scheduling: The operating system schedules processes, allocating CPU time to each process independently. Threads within a process share the CPU time allocated to that process.


It's important to note that Java provides built-in support for threads through the Thread class and related APIs. Processes, on the other hand, are managed by the operating system rather than the Java language itself.






Saturday, June 17, 2023

Difference between Thread vs Runnable interface in Java

 In Java, both the Thread class and the Runnable interface are used for creating and managing concurrent threads of execution. They serve similar purposes but differ in their implementation approach. Here are the key differences between the two:


Inheritance vs Interface: The Thread class is a concrete class that extends the java.lang.Thread class, making it capable of directly creating and managing threads. On the other hand, the Runnable interface is implemented by a class, and the class can be used to create a Thread object using the Runnable instance.


Extending vs Implementing: To create a thread using the Thread class, you need to extend it and override its run() method. This allows you to define the code that will be executed in the thread. In contrast, to use the Runnable interface, you need to implement the run() method in a separate class. The run() method contains the code that will be executed when the thread is started.


Reusability: The use of Runnable interface provides better reusability than extending the Thread class. With Runnable, you can implement the interface in multiple classes and create threads from different instances of those classes. This promotes a more flexible and modular design by separating the task logic from the thread management.


Single Inheritance Constraint: Java allows a class to extend only one class, which means if you extend the Thread class, you cannot extend any other class. However, by implementing the Runnable interface, you can still extend another class and implement Runnable, as Java supports multiple interfaces.


Encapsulation: Implementing Runnable separates the task (defined in the run() method) from the thread's behavior, allowing better encapsulation. It enables you to pass the Runnable instance to different thread constructors, promoting code reuse and modularity.


Resource Sharing: When multiple threads need to share resources or data, implementing Runnable is generally preferred. By passing the same instance of the Runnable implementation to multiple threads, they can access and manipulate shared resources easily. In contrast, extending the Thread class may lead to limitations in resource sharing.


In summary, the Thread class provides a convenient way to create and manage threads, while the Runnable interface offers a more flexible and reusable approach to defining thread behavior. The choice between the two depends on the specific requirements of your application and the design principles you want to follow.






Saturday, May 27, 2023

How to Implement Thread in Java with Example

In Java, you can implement threads by creating a class that extends the Thread class or by implementing the Runnable interface. 

Here's an example of both approaches: 

Approach 1: Extending the Thread class


public class MyThread extends Thread {
    @Override
    public void run() {
        // Code to be executed in the thread
        System.out.println("Thread is running");
    }

    public static void main(String[] args) {
        // Create an instance of the custom thread class
        MyThread thread = new MyThread();

        // Start the thread
        thread.start();
    }
}

Approach 2: Implementing the Runnable interface


public class MyRunnable implements Runnable {
    @Override
    public void run() {
        // Code to be executed in the thread
        System.out.println("Thread is running");
    }

    public static void main(String[] args) {
        // Create an instance of the custom runnable class
        MyRunnable myRunnable = new MyRunnable();

        // Create a Thread object and pass the runnable instance
        Thread thread = new Thread(myRunnable);

        // Start the thread
        thread.start();
    }
}

Both approaches achieve the same result of creating and running a new thread. The run() method contains the code that will be executed in the thread. In the example, it simply prints a message, but you can replace it with any desired functionality. 

To start a thread, you need to call the start() method on the Thread object. This will internally invoke the run() method, executing the code in a separate thread of execution. 

It's important to note that when extending the Thread class, you directly override the run() method. 

When implementing the Runnable interface, you define the code in the run() method of the Runnable implementation, and then create a Thread object passing the Runnable instance as a parameter. Both approaches have their advantages. 

Extending the Thread class allows direct access to all the features of the Thread class, while implementing the Runnable interface provides better flexibility, as it allows the class to extend other classes if needed.

Remember, in a multithreaded environment, the order of execution of threads may vary, so the output may not always be in a specific order.