Multithreading in Java – Important Facts That You Should Know

Get Job-ready: Java Course with 45+ Real-time Projects! - Learn Java

Before we dive into the topic Multithreading in Java, it is essential to know what multithreading actually is. For this, let us take into account the following example.

You are the head chef and the only chef of your newly started restaurant. You have a feeling that this organization may reach heights.

But you are not too confident and decide to be the only chef of the restaurant for the time being. B

ut one day, you serve a very popular person a dish which changes the way he thinks about food. He loves your biriyani and decides to write about your restaurant in the most popular newspaper of your time.

People start flocking all over your restaurant the day after and you are exhilarated at the response.

But this may be a problem for you because you are the only chef and preparing food for over 300 people every day is not an easy task.

So you do what each and every good manager does, you decide to employ new chefs and teach them your recipe. This essentially eases your job and now you can serve all people with ease.

This employment of multiple people from the same job is known as multithreading where each chef is a thread and the ultimate goal is to feed all the people in your restaurant with the dish they desire.

If you already know Javascript and asynchronous programming in it, you might be confused as to what is multithreading and what is the difference between asynchronous programming and multithreading actually is.

Do not worry we will be having a section denoting the differences between them at the end of the article.

What is Multithreading in Java?

Multithreading is the process of executing two or more threads of the same process simultaneously.

Keep in mind that multithreading and multiprocessing are different in nature.

Multi-threads share the CPU resources, however, threads are a part of a process. Think of a process as the act of providing the food to the customers and the threads being the cooks you assign to do the job.

You can also think about threads as light-weight sub-processes that simultaneously work to perform a particular process.

States of Threads in Java

Before we dive into the classes and objects related to multithreading in Java, let us look at the threads and their states in Java.

States of threads in Java

Each thread exists in either one of these states:

1. NEW – As the name suggests, a thread that is brand new and still idle is in this state.

2. RUNNABLE – When a thread is executing in the JVM(Java Virtual Machine) it is said to be in the RUNNABLE state. A very important thing to note here is that the thread might be running or is getting to run in an instant when it is in the RUNNABLE state. The thread scheduler allocates the necessary resources and time of running to each thread in the RUNNABLE state.

3. BLOCK – The thread is waiting for a monitor lock when it is in the BLOCK state. This means that the thread is waiting for a particular I/O operation to complete.

4. WAITING – This is similar to the BLOCK state, however in this state the thread is waiting for a different thread for some reason.

5. TIMED_WAITING – In this state, the thread is waiting for a particular timeout function to finish. After it finishes the thread is in the RUNNABLE state again.

6. TERMINATED – Quite simply this means that the thread is now no longer alive. This may be because of two reasons, either the thread has completed all its operations or it has encountered a serious problem such as a segmentation fault.

Some Important Terms

1. Multitasking

This essentially means performing multiple actions at the same time. When you listen to music and code, you are essentially multitasking.

2. Multithreading

This means the action of multiple threads of a single process working simultaneously to complete a single process.

3. Multiprocessing

This may seem similar to multithreading but there is a fundamental difference in it that sets them apart.

Multiple processing involves the use of multiple cores of the CPU whereas multithreading uses only a single core of the CPU.

4. Parallel Processing

This again means the parallel usage of CPU cores of a particular computer system.

Enough theory already! Let us look at some live examples of multithreading in Java.

How to Create Threads in Java?

There are two ways by which we can create threads in Java.

One of them is:

  • By extending the Thread class
  • By implementing the Runnable Interface

But before we start implementing multithreading, it is essential that we know what these methods of the Thread class mean.

  1. getName(): This returns the thread name.
  2. getPriority(): This returns the priority of the thread.
  3. isAlive(): This method is useful for checking whether the thread is still running.
  4. join(): This method waits for a thread to terminate.
  5. run(): This method invokes the start of the thread. This method is generally used to denote the actions the thread will perform.
  6. sleep(): This method suspends the thread for a particular period of time.
  7. start(): start a thread by calling its run() method

Program to illustrate the Java Thread class:

package com.dataflair.multithreading;
class Work extends Thread
{
    public void run()
    {
        for(int i=0;i<=10;i++)
        {
            System.out.println("The thread "+Thread.currentThread().getName()+" is running");
        }
    }
}

public class ExtendThread
{
    public static void main(String[] args) {
        Work a1= new Work();
        a1.setName("Thread 1");
        Work a2=new Work();
        a2.setName("Thread 2");
        a1.start();
        a2.start();
    }
}

Output:

The thread Thread 1 is running
The thread Thread 2 is running
The thread Thread 1 is running
The thread Thread 2 is running
The thread Thread 1 is running
The thread Thread 2 is running
The thread Thread 1 is running
The thread Thread 2 is running
The thread Thread 1 is running
The thread Thread 1 is running
The thread Thread 1 is running
The thread Thread 2 is running
The thread Thread 2 is running
The thread Thread 2 is running
The thread Thread 2 is running
The thread Thread 2 is running
The thread Thread 2 is running
The thread Thread 2 is running
The thread Thread 1 is running
The thread Thread 1 is running
The thread Thread 1 is running
The thread Thread 1 is running

As you can see the Threads 1 and 2 run simultaneously.

When you run the output you may get a different output based on how your thread manager associates the work to the threads.

Java program to illustrate the use of Runnable Interface in Java:

package com.dataflair.multithreading;
class Working implements Runnable {
    public void run() {
        for (int i = 0; i <= 10; i++) 
        {
            try 
            {   System.out.println("The thread " + Thread.currentThread().getName() + " is running");
                Thread.sleep(1000);
            } 
            catch (InterruptedException e) 
            {
                System.out.println("There has been an error"+e.getMessage());
                e.printStackTrace();
            }
        }
    }
}


public class ImplementRunnable {
    public static void main(String[] args) {

        Working w1=new Working();
        Working w2=new Working();
        Thread t1=new Thread(w1);
        Thread t2=new Thread(w2);
        t1.setName("Thread 1");
        t2.setName("Thread 2");
        t1.start();
        t2.start();
        
    }
}

Output:

The thread Thread 1 is running
The thread Thread 2 is running
The thread Thread 1 is running
The thread Thread 2 is running
The thread Thread 1 is running
The thread Thread 2 is running
The thread Thread 1 is running
The thread Thread 2 is running
The thread Thread 1 is running
The thread Thread 2 is running
The thread Thread 1 is running
The thread Thread 2 is running
The thread Thread 1 is running
The thread Thread 2 is running
The thread Thread 1 is running
The thread Thread 2 is running
The thread Thread 1 is running
The thread Thread 2 is running
The thread Thread 1 is running
The thread Thread 2 is running
The thread Thread 1 is running
The thread Thread 2 is running

Now that we have implemented a sleep function so that you can see the threads at work. Each thread will sleep for one second.

Now you must be thinking as to why we don’t call the run method directly? Why do we need to call the start method which then calls the run method?

Well if we directly call the run method then the JVM interprets it as a normal method call and cannot assign a thread to it.

However, the start method has some special implementations by which the JVM assigns a thread to the function.

You can try explicitly calling the run() method but there will be no threads initiated and the method will run in a single thread.

If you want you can check out the implementation of the “void java.lang.Thread.start()” method and you will observe how it is assigning a different thread to the run method.

Priorities of Threads in Java

The priorities of threads are simply numbers that are essential for determining the priority of a thread, that is, how a thread is actually treated in respect to other threads.

Context switching is the process of switching the running thread from one thread to another.

We can set the priority of the threads that we use by using the setPriority() method. The values for the setPriority() method can be MIN_PRIORITY, NORM_PRIORITY, OR MAX_PRIORITY.

A higher priority thread can replace a low priority thread from being executed.

isAlive() and join() Methods in Java

Java isAlive() method checks whether the thread is alive or not. If a thread is alive, it returns true else it returns false.

We can also use the join() function. When a parent thread calls the join function, it waits till the child thread finishes execution.

Synchronization in Java

Consider the like counter of a popular Twitter post. At every millisecond there are thousands of likes floating in.

Due to multiple threads accessing the counter at the same time. Now it may happen that due to the multiple reads and writes at the same time the like counter may calculate incorrectly.

To avoid this, there is a concept called synchronization.

This basically boils down to the fact that when a particular memory resource is being used by a thread a new thread cannot access that resource.

It has to wait for the first thread to finish execution on the resource and only then can the second thread access the value.

Synchronized(Object)
{However, some functions do not support synchronization out of the box. For those methods Java allows them to be put in a Synchronized block.

//Code
}

Inter Thread Communication

The methods that are essential for inter-thread communication are wait(), notify(), and notifyAll().

In Java, the monitor prevents other threads from using the resource if a particular thread is using it at present. This is because the monitor can hold only one thread.

The wait method asks the monitor to give up the threads and go to sleep.

  • notify() – This wakes up the first thread which was put on the wait() queue.
  • notifyAll() – This wakes up all the threads which are sleeping.

Out of these threads, the one which has the highest priority will run first.

Difference Between Process and Thread in Java

Although these are very similar in nature they are quite different and we will look at them now.

ProcessThread
Process is a program running on a computerA thread is a part of a process. A single process can have many threads. 
Faster context switching as they are more resource-heavyThese are fast in changing contexts because they are not resource-heavy.
A single process does not share memory with other processes.A thread shares memory and other resources with other threads. 
Communication in between processes takes time. Communication within threads is faster. 
If a single process is blocked in memory, other processes can still run. All other threads are blocked if a particular user-level thread is blocked. 
They use a lot of computer resources.They are lightweight and do not use too much resources. 
There are different data and code segments for different processes. The peer threads share both the code and the data segments
The operating system treats all processes in a CPU differently. The operating system treats threads of the same program segment as a single task. 
It takes longer to create a processIt does not take much time to create a new thread. 
Terminating a process takes a considerable amount of time. Terminating a thread is much faster than a process. 

Difference Between Asynchronous and Multithreading in Java

Programmers who are from a Javascript background often get confused as to what the difference between multithreading and asynchronous actually is.

Well, this is best explained by an example.

Remember when we talked about you being a chef and owner of a restaurant that became very popular in a short amount of time?

Well, when you are cooking alone, you yourself are one thread of execution. If you want to make an omelette, you break the eggs and make the batter.

Then you turn on the gas and wait for the pan to turn warm. While the pan is getting warm you decide to clean the sink of your kitchen.

As soon as you observe that the pan is warm enough for the eggs, you drop your work in the sink and pour the eggs onto the pan. Then you return back to the sink.

Notice how you are the only one in the kitchen(Signifying one thread) and instead of doing absolutely nothing and waiting for the pan to get warm, you decide to finish other tasks in the meanwhile.

There is only one thread but the thread jumps between the code segments and finishes other tasks while one action is taking time to execute.
This is asynchronous programming. It prevents the blocking of code.

However, when you employ 4 people in your kitchen, each of these chefs perform their duties individually. None of them wait for one another.

This simultaneous working of the chefs is multithreading where each and every chef is a thread inside the process that is your restaurant.

Multithreading is a part of asynchronous programming at its core.

So when should you use which? Well, it depends. When you work for a company with a huge codebase you will have to implement both asynchronous and multithreading aspects into the codebase. This will prevent blocking and will result in responsive I/O.

Advantages of Multithreading in Java

As you might have guessed there are plenty of advantages to multithreading in Java. Some of them are:

  • It results in a non-blocking code.
  • Saves time because we can perform many different operations at the same time.
  • A single thread does not affect other threads.

Summary

We learned about the various steps needed to implement multithreading in Java.

Multithreading is an extremely important concept and a tricky one to master. It requires practice. This topic is also favourite for many interviewers.

Did we exceed your expectations?
If Yes, share your valuable feedback on Google

courses

DataFlair Team

DataFlair Team creates expert-level guides on programming, Java, Python, C++, DSA, AI, ML, data Science, Android, Flutter, MERN, Web Development, and technology. Our goal is to empower learners with easy-to-understand content. Explore our resources for career growth and practical learning.

1 Response

  1. Abu Bakkar says:

    Big Data Advantages: Key Features
    The big data challenges are the main features of big data. All that big data achieves is all that big data can offer to the person in its technical capacity. So, here are the key features of big data that will show how it can be used for manipulation of the data in hand.
    The Data Collection:
    The data collection in the modern world is a complex concept. The data that comes to the storage system is in an unprecedented amount because modern technology has automated the data collection. The storage includes a regularly calibrated increase in the new entries and cataloging them automatically. That is the early key feature of data analytics.
    Data Analysis:
    The data analysis is a process that includes data research, data sharing, data transfer and using the data to develop useful insights. Data analysis used to be a solely human endeavor but with artificial intelligence, the computers can analyze the data and make authentic conclusions on the data in place.
    Information Privacy:
    In the modern world of big data and artificial intelligence, data privacy is a core necessity of the modern world. The aim is to make sure that the data does no into malicious users’ grasp. That is a shift from the former concept where data was not shared with any individual outside of the personal sphere of the person at all.
    Data Source:
    The data source is also a significantly more secured entity in this generation. Before the source had to allow an external human being into their system but now the data is computerized. It can only be accessed by a computer and not a real person. There is also a danger in this concept because the fact is that computer hacking will now have immense power in the digital world.
    Visualization:
    Visualization is the process of taking the data and presenting it in a practical and interactive manner. This concept is also much more complex because when there was a limited amount of data available then the data was also presented easily. But now that the data is present in millions and billions, the data presentation also becomes much more extensive and complex.
    All in all, data analytics is a great skill to have as it will be the future of the world. It is going to play an extensive role in the future of humanity.

Leave a Reply

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