Java

Multithreading in Java | Explained

Java provides a feature named Multithreading which allows simultaneous execution of multiple threads and as a result, it improves CPU utilization, resource sharing, user response, and so on. Multithreading is used frequently because threads utilize the shared memory area and hence there is no need to allocate separate memory to any thread consequently, it saves memory, and performs fast execution. The most common real-world use cases of Multithreading involve computer games, animations, and so on.

This write-up presents a complete guide of multithreading in java and for a profound understanding, it will cover the following concepts:

So, let’s get started!

What is Multithreading

It is a process that allows us to execute at least two threads at the same time and it is also referred to as concurrency in java. Java multithreading maximizes the CPU utilization as it runs every thread parallelly. Moreover, it saves memory as in multithreading there is no need to allocate separate memory to Multiple threads.

Why Multithreading is Important in Java

Multithreading provides a broad range of features and the significance of Java Multithreading can be evaluated from the below-listed features:

  • Java multithreading allows resource sharing hence within a process multiple resources can be shared such as code, memory, files, data, and so on.
  • Threads are independent therefore exceptions that occurred in one thread wouldn’t affect the performance of others.
  • Multithreading in java enables a program to run even if a specific piece of the program is blocked for some reason or executing a lengthy task/operation.
  • It saves time as multiple tasks/operations can be performed simultaneously.

Only a few features are listed here, however, there are many more like scalability, cost-effectiveness, etc. that show the dominance of multithreading.

Life Cycle of Threads in Java

As of now, we have learned what is multithreading and why is it so important in java? Now we will learn about the thread’s life cycle which is comprised of various states as listed below:

New: In this state, a thread is initiated/created using the “Thread” class or “Runnable” interface. It stays within this state until a program starts/initiates a thread.

Runnable: Within this state, the thread’s instance will be invoked using a built-in method start() and the thread stays in the runnable state until a task is executing.

Running: In this state, a thread starts the execution.

Waiting: within this phase, the thread goes to a temporarily inactive state which means either a thread is sleeping, waiting, or in a blocked state.

Terminated/Dead: A thread enters in this state when an exception occurs or if the thread completes its execution/processing.

Java Build-in Methods for Multithreading

There is a list of java predefined methods that can be used within the threads to achieve different functionalities. Some frequently used methods are listed in the below-given table:

Method Name Description
start() It is used to start the thread’s execution.
run() performs specific action for a thread.
getName() returns the thread’s name.
yield () Halts the current thread and allows others to execute.
setPriority(int newpriority) Specifies the thread’s priority.
getPriority() returns thread’s priority.
Sleep(int milliseconds) Sleeps the thread for a specified time period.
getId() returns thread’s id.

Practical Implementation of Multithreading in Java

Now, it’s time to understand the concept of java multithreading using practical implementation. So, we are going to consider an example where we will perform multithreading and will utilize some of the above-mentioned built-in methods.

Example

In this example we will perform the multithreading by implementing the runnable interface:

public class MultithreadingExample implements Runnable {
    @Override
    public void run() {
    }
    public static void main(String[] args) {
        Thread threadObj1 = new Thread("Thread1");
        Thread threadObj2 = new Thread("Thread2");
        threadObj1.start();
        threadObj2.start();
        System.out.println("Name of First Thread: " + threadObj1.getName());
        System.out.println("Name of Second Thread: " + threadObj2.getName());
    }
}

In the above code snippet, we implement the Java Runnable interface, and within the class, we utilize the @Override annotation which shows that the “MultithreadingExample” is overriding the run() method of Runnable interface. Afterward, we create multiple threads and start the thread’s execution using the start() method. Finally, we get the thread’s names using the getName() method and print them as shown in the below snippet:

This verifies the working of multi-threads in java.

In the example above, we perform multithreading by implementing Runnable interface. However we can also perform multithreading by extending a predefined Thread class as shown in the following snippet:

public class MultithreadingExample extends Thread

By extending the Thread class you can avail the functionalities of predefined Java methods.

Conclusion

Multithreading allows simultaneous execution of two or more threads which maximizes the CPU utilization, saves time, memory, etc. Multithreading can be performed by extending or implementing the Thread class or Runnable interface respectively. Various built-in methods of Thread class and Runnable interface can be used in multithreading to perform different functionalities such as Halting the current thread and allowing other threads to execute, specifying priority to the threads, and so on.
This write-up explains different aspects of multithreading such as what is multithreading, its importance, life cycle, methods, and practical implementation.

About the author

Anees Asghar

I am a self-motivated IT professional having more than one year of industry experience in technical writing. I am passionate about writing on the topics related to web development.