Java Multithreading – ‘Coz your Java knowledge is Incomplete without it

Multithreading is another important feature of Object-Oriented Programming. Multithreading in Java helps more than two programs simultaneously execute and we can utilize the capacity of CPU.

In this Java tutorial, we will learn what multithreading is, the advantages of using it and how to implement multithreading in Java.

Before discussing multithreading in Java, we should know about the threads in Java. So let’s begin with the threads in Java.

What is a Java Thread?

A thread is just a single lightweight and smallest part of a process. It is the smallest unit of a process that can run concurrently with the other parts (other threads) of the same process.

There can be multiple processes in an Application. Each process can have a single thread or multiple threads. Multithreading is the process of concurrent execution of multiple threads.

There is a common memory area for all threads of a process but each of them is independent of each other because they all have separate paths of execution. Therefore, if an exception occurs in one thread, it does not affect the execution of other threads.

The above figure shows that a thread executes inside the process. There is context-switching between the threads. There can be multiple processes inside the Operating System, and there can be multiple threads in one process.

Note: At a time only a single thread can be executed.

Multitasking vs Multithreading vs Multiprocessing vs Multiprogramming

You would be having confusion with Multitasking, Multithreading, Multiprocessing, and Multiprogramming. Lets briefly compare them to have a better understanding of all of them.

Multitasking: Multitasking is the capability of an Operating System to execute more the one task or job simultaneously on a shared resource.

Multithreading: Multithreading is the ability of an Operating System to execute more than one thread at the same time. Here, a single process is divided into multiple threads.

Multiprocessing: It is similar to multitasking but here there is more than one processor or CPU. Therefore, multiple processes can execute with the multiple processors at the same time.

Multiprogramming: Multiprogramming is the ability to run more than one program at the same time within a single machine. For example, running Excel and Firefox simultaneously.

Thread Priorities in Java

With the creation of Java thread, the JVM assigns it some priority that helps the operating system determine the order of scheduling the threads. We can also set the priority of the thread in an explicit manner.

The valid range of a priority of a thread is from 1 to 10. Threads that have higher priorities should be allocated before the threads with the lower priorities.

3 Constants of defining Thread Priorities

There are 3 types of static variables or values for defining Thread priorities. The table shows these variables:

Variable Description
public static int MIN_PRIORITY The minimum priority of a thread with value = 1
public static int NORM_PRIORITY The default priority of a thread with value = 5
public static int MAX_PRIORITY The maximum priority of a thread with value = 10

Java Thread Life-Cycle

Threads exist in several states. The above figure shows the various stages of the thread which are:

  1. New state
  2. Runnable state
  3. Running state
  4. Waiting state
  5. Dead state

1. New

The thread is the new state when we create it using the “Thread class”. It remains in this state until the program starts the thread by calling the start() method. It is also called a born thread.

2. Runnable

In this phase, the start() method invokes the instance of the thread. The scheduler takes the thread control to finish the execution. It depends on the scheduler whether to run the thread or not.

3. Running

The thread goes to the running state when its execution starts. The scheduler selects one thread from the thread pool and the thread starts executing in the application.

4. Waiting

There is a need for synchronization between threads as multiple threads are running in the application. Hence, one thread has to wait, till the other thread finishes its execution. Therefore, we say that the thread is in the waiting state.

5. Dead

When the thread is terminated, the thread goes into the dead state.

Advantages of the single thread

The benefits of using threads are:

  • A thread reduces the overhead in the application as a single thread runs in the system
  • A single thread reduces the maintenance cost of the application.
  • Threads have a shared memory area so they help to save memory.
  • Context-switching between the threads takes less time than the process.

Multithreading in Java

The process of running more than one thread in a program or an application concurrently or simultaneously is called Multithreading in Java. When more than two threads run concurrently, it is multithreading.

Therefore, we can also call it Concurrency in Java. Multi-threading allows multiple activities to execute concurrently in the same program so as to achieve the maximum utilization of CPU.

As discussed above, Multitasking is a process of running or executing multiple processes or tasks at the same time.

Multi-threading expands the idea of multitasking where we can separate a single application into individual threads and run each thread independently within the same memory space. Each thread in a multi-threaded program can run in parallel.

The Operating System divides the processing time among different applications and also among each thread within an application.

Methods of Thread Class in Java

The following list shows some important methods available in the Thread class.

S.N. Method Description
1 public void start() This method begins the thread execution in a separate path and then calls the run() method on the current Thread object.
2 public void run() Runnable object invokes this method if we instantiate this Thread object using a separate Runnable target.
3 public final void setName(String name) This method changes the name of the Thread object. 
4 public final void setPriority(int priority) We use this method to set the priority of this Thread object. We can use possible values between 1 and 10.
6 public final void join(long millisec) The current thread calls this method on a second thread and causes the current thread to block until the second thread terminates for the specified number of milliseconds passes.
7 public void interrupt() This method interrupts the current thread and causes it to continue execution if it had been blocked for any reason.
8 public final boolean isAlive() It returns true if the thread is alive or is still running, else it returns false.
9 public static void yield() It causes the currently running thread to yield to any other threads of the same priority that are waiting for being scheduled.
10 public static void sleep(long millisec) It halts the currently running thread for at least the specified number of milliseconds.
11 public static Thread currentThread() It returns a reference to the currently running thread, i.e the thread that invokes this method.

How to Achieve Multithreading in Java?

We can achieve multithreading in Java in two ways:

  • By Implementing the Runnable Interface
  • By extending Thread class

Let’s discuss these two ways in detail

1. Implementing the Runnable Interface in Java

Creating a class by Implementing the Runnable interface is the simplest way to create a thread. To do this we need a class that implements a single method called run( ). To create a thread using a Runnable interface, you will need to follow three basic steps:

Step 1

In the first step, you need to implement the run() method of the Runnable interface. This method acts as an entry point for the thread and your complete business logic will be present inside this method. The syntax of the run() method is as follows:

public void run( )

Step 2

In the second step, you will instantiate a Thread object using the following constructor:

Thread(Runnable threadObject, String threadName);

Where threadObject is an instance of a class that implements the Runnable interface and threadName is the name of the new thread.

Step 3

Once you create a Thread object, you can start it by calling the start() method, which makes a call to the run( ) method. Following is a simple syntax of the start() method:

void start();

Code to create a thread by implementing the Runnable interface:

package com.techvidvan.multithreading;
class MultithreadingDemo implements Runnable
{
  public void run()
  {
    try
    {
      System.out.println ("Thread " +Thread.currentThread().getId() +" is running");
    }
    catch (Exception e)
    {
      System.out.println ("Exception caught");
    }
  }
}
public class ImplementingRunnableInterface
{
  public static void main(String args[])
  {
    for (int count=0; count<5; count++)
    {
      Thread object = new Thread(new MultithreadingDemo());
      object.start();
    }
  }

}

Output:

Thread 11 is running
Thread 13 is running
Thread 12 is running
Thread 14 is running
Thread 15 is running

2. Extending the Thread class

We can also create a thread by creating a new class that extends the Thread class. Then, this class overrides the run() method and then we create an instance of this class. When you call the start() method, the run() method executes.

Creating thread using Thread class is more flexible than creating it through the Runnable interface Because it is easy to handle multiple created threads using available methods in Thread class.

Here is a simple step-by-step process of creating a Java Thread subclass:

Step 1

As the first step, you need to override the run( ) method of the Thread class. This method is an entry point for the thread and all the business logic is present inside this method.

The syntax of the run() method is as follows:

public void run( );

Step 2

Once you create an object of the Thread subclass, you can start it by calling the start() method, which makes a call to the run( ) method. Following is a simple syntax of the start() method:

void start( );

Code to create a thread by extending the Thread class:

package com.techvidvan.multithreading;
class MultithreadingDemo extends Thread
{
  public void run()
  {
    try
    {
      System.out.println("Thread " +Thread.currentThread().getId() +" is running");
    }
    catch (Exception e)
    {
      System.out.println ("Exception caught");
    }
  }
}
public class ExtendingThreadClass
{
  public static void main(String[] args)
  {
    for (int count=0; count<5; count++)
    {
      MultithreadingDemo object = new MultithreadingDemo();
      object.start();
    }
  }
}

Output:

Thread 11 is running
Thread 12 is running
Thread 13 is running
Thread 14 is running
Thread 15 is running

Advantages of Multithreading in Java

  • Multithreading allows multiple operations to perform at once.
  • It saves time as there can be the execution of multiple operations possibly.
  • Threads are independent of each other which makes the functionality better.

Summary

From this article, we came to know that Java is a multi-threaded programming language which means we can develop a multi-threaded program using Java. With multithreading in Java, we can divide a particular task within a single application into multiple threads.

The start() method starts the execution of the code written in the run() method. If you omit the start() method in your code, the code inside run() also doesn’t execute!!

So, now you know the life cycle of the thread and how to achieve multithreading in Java. There are many methods in a thread class that we covered in this article. Multithreading will definitely help you to enter into the world of the gaming industry.

Thank you for reading our article. If you have any queries related to Java Multithreading, do let us know by dropping a comment below.

Happy Learning 🙂