Multithreading Program in Java

In this article, we will learn the basics of multithreading and write a multithreading program in Java to illustrate the concepts that we will learn. We will discuss what are processes and programs, what are threads, threads and processes interdependence, what is the need for multithreading, multithreading program in Java using the Thread class, and multithreading program in Java using the Runnable interface. So, let’s get started.

What are Processes and Programs?

We know that the applications that we use on our computers are nothing but programs (or a collection of programs called software). When we open any application, it is these programs that get executed and we get to interact with these programs using another program (or software) called the Operating System.

So, if we think carefully, these programs can be only in 2 stages i.e. under execution and not under execution. It is simply that any application on your computer is either being used or is not being used. So, the programs that are being used or are under execution are called processes.

So, the difference between a program and a process can be understood by the following statement; “A process is a program under execution.”

Now that we have understood the meaning of processes and programs, let us now study what are threads.

What are Threads?

A thread is the smallest unit of a process. Yes, it is very important to understand that a thread is the smallest unit of a process and not a program because a program is not executing and a process is executing. We can understand this with the help of an example. Now please note that this is just an example to illustrate what threads are and not exactly how the threads work.

Consider you are using Microsoft Word on your PC/laptop. In this application, say you are writing an article. So, Microsoft Word is itself a process because it is a program under execution. In Microsoft Word only, there are multiple threads that are running together. For instance, you are typing and the typed content is being shown on the screen. This can be considered as a thread. Another thread can be spell check while you are typing. Auto-saving is another thread running simultaneously.

So, this is what threads are. Threads are the smallest parts or units of processes and threads combine to form a process. Now, let us study whether the threads and processes are interdependent on each other or on other processes and threads or not.

Threads and Processes Interdependence

The different processes running on a machine are actually independent of each other. This is because the running of the Microsoft Word application has nothing to do with the running of the Chrome Browser, for instance.

However, there might be some part of the code that might be common in the 2 processes. This common code part that deals with either a shared variable between the processes or a shared resource is called a Critical Section.

However, this Critical Section is dealt with by the Operating System using Process Synchronization.

So, to keep it short, the processes are independent of each other in general and if they depend upon each other because of the critical section problem, it is dealt with using process synchronization.

The threads however are dependent on each other. This is because threads are smaller units of the same process. Hence, they depend on each other. So, the interdependence of threads is also dealt with by a concept called thread synchronization.

Now that we have understood the thread and process concepts in detail, let us study the need for multithreading.

What is the need for Multithreading?

The simple reason for the need for multithreading is to increase performance. Today, processors come with multiple cores and we can run different threads on these different cores simultaneously to improve performance and increase the speed of execution.

Fun Fact: You can know the number of cores in your CPU if you are a windows user by going to the task manager and clicking the performance tab.

Now that we have understood the meaning of processes, threads, and the need for multithreading, let us now try to write a multithreading program in Java.

Multithreading Program in Java – Using the Thread Class

Consider the following program written below.

Hello-Hi Program in Java

class Hello {
    public void run() {
        for(int i=1;i<=5;i++) {
            System.out.println("Hello");
        }
    }
}
class Hi {
    public void run() {
        for(int i=1;i<=5;i++) {
            System.out.println("Hi");
        }
    }
}
public class Main {
    public static void main(String[] args) {
        Hello t1 = new Hello();
        Hi t2 = new Hi();
        t1.run();
        t2.run();
    }
}
 

What do you think is the output of this program? Well, we have first called the run() method of the Hello Class, and then we call the run() method of the Hi() class. The run() method of the Hello class is supposed to print “Hello” 5 times and the run() method of the Hi class is supposed to print “Hi” 5 times. So, the output should be 5 times “Hello” and then 5 times “Hi” as shown below.

This is the correct output. So, from this, we need to understand one concept called the main thread. Actually, every program in Java will run from top to bottom and left to right in fashion. So, if the run() method of the Hello class is called first, it will complete its execution first, and then only the run() method of the Hi class will start its execution.

If we want to make Hello and Hi print randomly and execute simultaneously, we need to create 2 threads of Hello and Hi respectively. This can be done by extending (inheriting) the Thread Class in Java.

The following program shows a multithreading program in Java using the Thread Class.

Multithreading Program in Java – Using Thread Class

class Hello extends Thread {
    public void run() {
        for(int i=1;i<=200;i++) {
            System.out.println("Hello");
        }
    }
}
class Hi extends Thread{
    public void run() {
        for(int i=1;i<=200;i++) {
            System.out.println("Hi");
        }
    }
}
public class Main {
    public static void main(String[] args) {
        Hello t1 = new Hello();
        Hi t2 = new Hi();
        t1.start();
        t2.start();
    }
}

Output:

We have shown a part of the output in the above image. It shows that a number of times “Hello” got printed and then suddenly in between “Hi” got printed a few times, then again “Hello” gets printed. Let us understand the code written above.

Explanation: The code above has 2 classes Hello and Hi and they both extend the Thread Class. The Thread class is a Class in java used to implement multithreading. The Thread class contains a method run() that needs to be overridden by the class extending the thread class to implement multithreading. So, the Hello and the Hi Classes have overridden the run() method respectively. Now, in the main() method, we create the objects of these classes and we have strangely not called the run() method. In fact, instead of the run() method, we have called a start() method that is not even defined in both classes.

This is actually how we implement multithreading in java. When the start() method is called (which is there in the Thread Class), it, in turn, calls the run() method of that particular Child class i.e. the Hi and Hello classes respectively in this case. So, this start() method invoking depicts that we have started a new thread. So, these 2 threads are started simultaneously and we are able to see in the output that they are getting executed together.

Obviously, here we are not able to get alternate “Hello” and “Hi” printed because the processor (CPU) is executing these threads with some context switching that we don’t know.

However, we can control it, we will see that in some other lesson. Let us now look at one more method to implement multithreading in Java.

Multithreading Program in Java – Using Runnable Interface

So, we saw the above multithreading program in Java using the Thread Class in Java. Let us implement the same using the Runnable Interface as shown below.

Multithreading Program in Java – Using Runnable Interface

class Hello implements Runnable {
    public void run() {
        for(int i=1;i<=200;i++) {
            System.out.println("Hello");
        }
    }
}
class Hi implements Runnable {
    public void run() {
        for(int i=1;i<=200;i++) {
            System.out.println("Hi");
        }
    }
}
public class Main {
    public static void main(String[] args) {
        Thread t1 = new Thread(new Hello());
        Thread t2 = new Thread(new Hi());
        t1.start();
        t2.start();
    }
}

Output:

So, the above image shows a part of the entire output. We can see that both the threads are being executed simultaneously. Let us now understand the above program in detail.

Explanation: Instead of extending the Thread class, we have now implemented the Runnable Interface. So, the concept of overriding the run() method remains the same. Also, we are calling the start() method in the main method() so that remains the same too. However, now we are not creating the objects of Hello and Hi classes. We have created the objcects of Thread class and have passed the objects of Hello and Hi classes as a parameter to the Thread() constructor. Again, calling the start() method calls the run() method of that particular class and we get our output.

So, these are the 2 ways to write a multithreading program in Java. We hope that you have understood the concept of process, program and threads and have also understood the need and ways of implementing multithreading.

Leave a Reply

Your email address will not be published. Required fields are marked *