Threads concept in Java.

Threads concept in Java.

Hello Everyone,

Hope you are doing well.

In this blog post, we will discuss threads, different types of threads, how we can implement them and learn the pros and cons of threads.

Let's begin now.

What is the Thread?

Thread is simply the extra utility arm which performs some tasks concurrently with the running application without any disturbance to the running state.

In Java, threads are pre-defined classes that are available in the java.package which provide the feature of concurrently running tasks in the application. Threads use the same memory, but they are independent means any exception in a thread will not affect how other thread work, despite them sharing the same memory location.

Types of Threads :

1. User Thread :

The user thread is the high-priority thread which runs in the foreground. In the case of a user thread, JVM quits an application when all user threads are completed in their running state. It doesn't care about daemon threads whether they are complete or not in a completed running state. An example is the main method of the class which is by default as user thread.

2. Daemon Thread:

The daemon thread is the low-priority thread which runs in the background they are generally terms as service thread. In the case of a daemon thread, JVM will not give preference to any daemon thread as soon as user thread completes it will shut down. Examples of daemon threads are garbage collector threads, clock handler threads etc.

How to create a user thread in java?

Thread implementation in java is achieved in mainly two ways :

1. By Implementing the Runnable interface.

The simplest way to create a thread is to create a class that implements the runnable interface. After implementing a runnable interface, the class need to implement the run() method then you need to explicitly create a Thread class object and need to pass the Runnable interface implemented class object as a parameter in its constructor in the main method.

package org.example;

class MyThread implements Runnable{
   public void run() {
        // Write your logic
        for(int i=0;i<3;i++) {
            System.out.println("MyThread is running  ");
        }
    }
}

class Main {
    public static void main(String[] args) {
        System.out.println("Main thread is  running ");
        MyThread demoThread = new MyThread();
        Thread thread = new Thread(demoThread);
        thread.start();
    }
}

Output:

Main thread is running
MyThread is running
MyThread is running
MyThread is running

Process finished with exit code 0

To call the run() method, we have to call start() method by which a new stack is provided to the thread and run() method is called to introduce the new thread into the program. The plus point of using the runnable interface is that we have the option to extend other class in our thread class.

2. By extending the Thread class

Another way to create a thread is by a new class that extends the Thread class and create an instance of that class. The extending class must override run() method which is the entry point of the new thread.

package org.example;

class MyThread extends Thread{
    @Override
    public void run() {
        // Write your logic
        for(int i=0;i<3;i++) {
            System.out.println("MyThread is running  ");
        }
    }
}

class Main {
    public static void main(String[] args) {
        System.out.println("Main thread is  running ");

        MyThread demoThread = new MyThread();
        demoThread.start();
    }
}

Output:

Main thread is running
MyThread is running
MyThread is running
MyThread is running

Process finished with exit code 0

Here, we must override the run() and then use the start() method to run the thread. Also, when you create myThread class object, Thread class constructor will be invoked, as it is the superclass, hence myThread class object acts as Thread class object. The main disadvantage of using this method to create a thread is that we can not extend any other class in our class.

As you can we in both ways our output is same.

How to create a daemon thread?

The implementation part of the daemon thread is the same as the user thread which you can refer to above, the change is that we have to use the setDaemon() method before start() method is invoked which takes a boolean value of either true or false.

package org.example;

class MyThread extends Thread{
    @Override
    public void run() {
        // Write your logic
        for(int i=0;i<99;i++) {
            System.out.println("MyThread is running  ");
        }
    }
}

class Main {
    public static void main(String[] args) {
        System.out.println("Main thread is  running ");

        MyThread demoThread = new MyThread();
        demoThread.setDaemon(true);
        demoThread.start();
    }
}

Output:

Main thread is running
MyThread is running
MyThread is running
MyThread is running
MyThread is running
MyThread is running
MyThread is running
MyThread is running
MyThread is running
MyThread is running
MyThread is running
MyThread is running

Process finished with exit code 0

Here, because of setting the thread as a daemon, we can see that loop inside myThread runs over 99 iterations but only for few numbers of times it runs due to low priority nature, as the user thread (main thread) completes its execution JVM quit the process and this thread remains unexecuted.

Conclusion

In conclusion, In Java Threads are lightweight compared to processes, it takes less time and resources to create a thread. And context switching between threads is usually less expensive than between processes.

Thank you for reading.