Dremendo Tag Line

Thread in Java

Thread in Java

In this lesson, we will learn how to create and use a thread in java.

What is Thread in Java?

A thread in Java is a lightweight and independent unit of execution within a process. A thread shares the same memory space as the process that created it, but each thread has its own stack, register set, and program counter.

By using threads, a Java program can perform multiple tasks at the same time, increasing its responsiveness and efficiency.

A Java program can use multiple threads executed simultaneously, allowing for more efficient use of system resources and improved performance.

Note: A program, when it starts executing, becomes a Process.

video-poster

How to Create Thread in Java

We can create a thread in Java in two ways and, they are:

  • By extending the Thread class.
  • By implementing the Runnable interface.

By Extending the Thread Class

To create a thread in Java, we can extend the Thread class and overrides its run() method to specify the code the thread will execute when it begins to run.

Syntax

class ClassName extends Thread
{
    public void run()
    {
        // write the code that you want to execute in a thread
    }
}

Example

class PrimeThread extends Thread
{
    public void run()
    {
        int i,j,fc;
        for(i=1; i<=100000; i++)
        {
            fc=0;
            for(j=1; j<=i; j++)
            {
                if(i%j==0)
                {
                    fc++;
                }
            }
            if(fc==2)
            {
                System.out.println("Prime Number = "+i);
            }
        }
    }
}

In the above program, we created a class known as PrimeThread by extending it with the Thread class. After that, we write code in the run() method we want to execute in a thread.

By Implementing the Runnable Interface

To create a thread in Java, we can implement the Runnable interface and overrides its run() method to specify the code the thread will execute when it begins to run.

Syntax

class ClassName implements Runnable
{
    public void run()
    {
        // write the code that you want to execute in a thread
    }
}

Example

class PrimeCountThread implements Runnable
{
    public void run()
    {
        int i,j,fc,pc=0;
        for(i=1; i<=100000; i++)
        {
            fc=0;
            for(j=1; j<=i; j++)
            {
                if(i%j==0)
                {
                    fc++;
                }
            }
            if(fc==2)
            {
                pc++;
            }
        }
        System.out.println("Total Prime Numbers between 1 to 100000 = "+pc);
    }
}

In the above program, we created a class known as PrimeCountThread by implementing the Runnable interface. After that, we write code in the run() method we want to execute in a thread.

How to Use Thread in Java

We know how to create a thread by extending the Thread class or implementing the Runnable interface. Now we will see how to use thread by using both methods one by one with examples.

Here is an example of using a thread by extending the Thread class:

Example

class PrimeThread extends Thread
{
    public void run()
    {
        int i,j,fc;
        for(i=1; i<=100000; i++)
        {
            fc=0;
            for(j=1; j<=i; j++)
            {
                if(i%j==0)
                {
                    fc++;
                }
            }
            if(fc==2)
            {
                System.out.println("Prime Number = "+i);
            }
        }
    }
}

public class Example
{
    public static void main(String args[])
    {
        // create an object of the PrimeThread class
        PrimeThread x = new PrimeThread();

        // execute the thread by invoking the
        // start() method of Thread class on object x
        x.start();
    }
}

If we run the above program, we will get the list of all the prime numbers between 1 and 100000.

Here is an example of using a thread by implementing the Runnable interface:

Example

class PrimeCountThread implements Runnable
{
    public void run()
    {
        int i,j,fc,pc=0;
        for(i=1; i<=100000; i++)
        {
            fc=0;
            for(j=1; j<=i; j++)
            {
                if(i%j==0)
                {
                    fc++;
                }
            }
            if(fc==2)
            {
                pc++;
            }
        }
        System.out.println("Total Prime Numbers between 1 to 100000 = "+pc);
    }
}


public class Example
{
    public static void main(String args[])
    {
        // create an object of the PrimeCountThread class
        PrimeCountThread x = new PrimeCountThread();

        // create an object of Thread class and
        // pass the object x as an argument to the constructor
        // of the Thread class.
        Thread t = new Thread(x);

        // execute the thread by invoking the
        // start() method of object t
        t.start();
    }
}

Output

Total Prime Numbers between 1 to 100000 = 9592

Note: We should create a thread by implementing the Runnable interface when we want to extend another class because Java does not allow extending a subclass with multiple classes. So if we create a thread by extending the Thread class, then there is no way to extend another class.

Create Multiple Threads in Java

We can create multiple threads in Java for doing multiple tasks parallelly. Suppose we want to find out the sum of all the perfect numbers between 1 and 10000 and also want to find the sum of all the prime numbers between 1 to 10000. We want to execute these two programs parallelly. To solve this problem, we will be creating two separate threads, one for each program. See the example given below.

Example

class PerfectCount extends Thread
{
    public void run()
    {
        int i,j,sum=0,fs=0;
        for(i=1; i<=10000; i++)
        {
            fs=0;
            for(j=1; j<i; j++)
            {
                if(i%j==0)
                {
                    fs=fs+j;	// sum of factors
                }
            }
            if(fs==i)
            {
                sum=sum+i;
            }
        }
        System.out.println("Sum of Perfect Numbers between 1 to 100000 = "+sum);
    }
}

class PrimeSum extends Thread
{
    public void run()
    {
        int i,j,fc,sum=0;
        for(i=1; i<=10000; i++)
        {
            fc=0;
            for(j=1; j<=i; j++)
            {
                if(i%j==0)
                {
                    fc++;
                }
            }
            if(fc==2)
            {
                sum=sum+i;
            }
        }
        System.out.println("Sum of Prime Numbers between 1 to 100000 = "+sum);
    }
}

public class Example
{
    public static void main(String args[])
    {
        PerfectCount t1 = new PerfectCount();
        PrimeSum t2 = new PrimeSum();

        // execute the thread by invoking the
        // start() method of object t1 and t2
        t1.start();
        t2.start();
    }
}

Output

Sum of Perfect Numbers between 1 to 100000 = 8658
Sum of Prime Numbers between 1 to 100000 = 5736396

In the above program, instead of the start() method, if we invoke the run() on objects t1 and t2, this will execute both programs sequentially (one after another) rather than parallelly. The run() method executes the program on the main thread, whereas the start() method creates a separate child thread and runs the program in its respective child thread.

Note: The main() method runs in a thread which is immediately created by the JVM (Java Virtual Machine) when our program starts, and this thread is called the main thread from where other child threads are created.

Let's see an example to understand the difference between the run() and start() methods.

By invoking start() method

class ThreadA extends Thread
{
    public void run()
    {
        int i,j;
        for(i=1; i<=10000; i++)
        {
            for(j=1; j<=100000; j++)
            {

            }
        }
        System.out.println("Exit from ThreadA");
    }
}

class ThreadB extends Thread
{
    public void run()
    {
        int i,j;
        for(i=1; i<=10000; i++)
        {
            for(j=1; j<=400000; j++)
            {
                // loop to create some execution delay in the program
            }
        }
        System.out.println("Exit from ThreadB");
    }
}

class ThreadC extends Thread
{
    public void run()
    {
        int i,j;
        for(i=1; i<=10000; i++)
        {
            for(j=1; j<=200000; j++)
            {
                // loop to create some execution delay in the program
            }
        }
        System.out.println("Exit from ThreadC");
    }
}


public class Example
{
    public static void main(String args[])
    {
        ThreadA a = new ThreadA();
        ThreadB b = new ThreadB();
        ThreadC c = new ThreadC();

        // execute the thread by invoking the
        // start() method of object a, b and c
        a.start();
        b.start();
        c.start();
        System.out.println("Hello Java");
    }
}

Output

Hello Java
Exit from ThreadA
Exit from ThreadC
Exit from ThreadB

The above program shows that on the output screen, first, Hello Java is displayed. After that rest of the messages from the threads appeared on the screen. It is because the start() method creates separate threads and starts executing the code parallelly without blocking the main thread.

Because the main thread is not blocked, it prints Hello Java on the screen without waiting for the other thread to be completed. It is an example of the parallel execution of codes using child threads in Java.

By invoking run() method

class ThreadA extends Thread
{
    public void run()
    {
        int i,j;
        for(i=1; i<=10000; i++)
        {
            for(j=1; j<=100000; j++)
            {

            }
        }
        System.out.println("Exit from ThreadA");
    }
}

class ThreadB extends Thread
{
    public void run()
    {
        int i,j;
        for(i=1; i<=10000; i++)
        {
            for(j=1; j<=400000; j++)
            {
                // loop to create some execution delay in the program
            }
        }
        System.out.println("Exit from ThreadB");
    }
}

class ThreadC extends Thread
{
    public void run()
    {
        int i,j;
        for(i=1; i<=10000; i++)
        {
            for(j=1; j<=200000; j++)
            {
                // loop to create some execution delay in the program
            }
        }
        System.out.println("Exit from ThreadC");
    }
}


public class Example
{
    public static void main(String args[])
    {
        ThreadA a = new ThreadA();
        ThreadB b = new ThreadB();
        ThreadC c = new ThreadC();

        // execute the run method of
        // object a, b and c
        a.run();
        b.run();
        c.run();
        System.out.println("Hello Java");
    }
}

Output

Exit from ThreadA
Exit from ThreadB
Exit from ThreadC
Hello Java

In the above program, we have not invoked the start() method on all the objects, so no separate child thread is created. We invoked the run() method on each object (a, b, and c), so they started executing sequentially.

When all the run() methods complete their execution sequentially, the last line in the main() method is executed and prints Hello Java on the screen. It is an example of the sequential execution of codes without creating child threads in Java.