Multithreading in Java

Multithreading in Java

6 mins read578 Views Comment
clickHere
Updated on Dec 5, 2022 18:54 IST

The below article goes through explaining the concepts of Multithreading in Java and its implementation. Let’s begin the tutorial.

2022_07_2.jpg

Concurrency nowadays has become an essential part of our lives while performing multiple tasks simultaneously. Concurrent programming consists of 2 significant concepts–Multitasking and Multithreading in Java.

Multitasking and Multithreading

Multitasking exists between a set of processes. Here, a process can work parallel to the program or application executing. They have their own address space to store instructions. As two processes have different address spaces, no synchronization is needed to access shared resources.

On the other hand, multithreading executes multiple tasks within the same application that needs synchronization.

Let’s understand the concept of Multithreading in Java in detail.

What is Multithreading in Java?

Multithreading is the process of executing multiple tasks within the same application that occurs between threads. 

A thread can be a lightweight process as it is a part of an existing process. Since a thread is a part of a process, it shares its address space. However, each thread has its own stack, program counter, and local variables. Java schedules multiple threads for these tasks.

For instance, a music application capable of playing, downloading, and searching music concurrently (at the same time). As multiple threads share the same address space of the application, synchronization is required here to ensure proper access to shared resources.

What is a Thread in Java?

Threads are like workers who have been assigned a certain task to be performed within the same application. How does it work? When a program starts, the JVM schedules the main thread to start executing it. FYI, the first thread to be created and executed inside any program is the main thread.

Also Read: Difference between JDK, JRE, and JVM

A single-threaded model begins with the main thread, and the following thread cannot initiate till the main thread ends. However, in the case of a multithreaded model, multiple tasks concurrently take place. The flow of the application starts with the main thread. However, the main thread can spawn into multiple threads.

Read: Access Modifiers in Java

Now, let’s see the life cycle of a thread to understand the concept better.

Life Cycle of a Thread

Like other processes, a thread undergoes a lifecycle from its creation to its termination. 

Following are the states in a lifecycle of a thread:

  1. New: When a thread is created, it is said to enter a new state. However, it is not alive at this moment.
  2.  Runnable: When a thread is ready to be assigned a processor but has not been assigned one, it is said to be in a runnable state. A thread enters a runnable state when the start() is invoked. Then it enters the alive state.
  3. Running: When a thread is allocated to a process, it comes in a running state. The run() method gets invoked at this state which defines the task is under process.
  4. Sleeping/Waiting/Blocked: A thread can switch from running to this state temporarily if it’s in sleep, wait or block. FYI, a thread can move to sleep for a time using the sleep() method. Moreover, a thread can go into a wait state and return when notified. Furthermore, a thread can go into a block state if any required resource is unavailable.
  5. Terminated: Once a thread completes the run() method, the execution ends, and the thread is considered terminated or dead.

The below diagram clears up the lifecycle of a thread.

thread-lifecycle

Note: A thread is alive in runnable and running states only. It is neither alive in the new state nor the terminated state.

Also, Read: Data Types in Java – Primitive and Non-Primitive Data Types Explained

Thread Class and Runnable Interface

The Thread class and Runnable interface are one of the most significant entities in multithreading. They both serve various methods that aid in the creation of threads. 

Below are a few of the essential constructors and methods in thread class and runnable interface.

Runnable Interface

As an interface cannot define any constructors. Therefore, the Runnable interface has constructors available.

Read: Interfaces in Java

Methods

Method Name Description
void run() Capable of defining the task to be performed by a thread.

For more information: Method Overloading in Java

Thread Class

The thread class implements the runnable interface. Therefore, it is responsible for defining the run() method.

Constructors

Constructors Description
Thread() Allocates memory to the new thread object.
Thread(Runnable target) It allocates memory to the new thread object to run a target.
Thread(Runnable target, String name) It allocates memory to the new thread object to run a target with a given name.
Thread(String name) It allocates memory to the new thread object with a given name.

Read: Constructors in Java

Methods

Methods Description
long getId() Returns a unique identifier for a thread as a long value.
String getName() It returns the name of the current thread as a string value.
int getPriority() Returns the priority of a thread object.
void join() Waits for a thread to finish execution.
Boolean isAlive() Checks whether the given thread is alive or not.
void run() It invokes when the thread starts its execution.
static Thread currentThread() Returns a reference to the currently executing thread.
void setName(String name) Set the name of the given thread.
void setPriority(int p) Set the priority of the given thread.
static void sleep(long milliseconds) Suspends the execution of the current thread for the given time in milliseconds.
void start() Starts the execution of a particular thread.

Read: Loops in Java

Difference Between C and Java
Difference Between C and Java
C and Java are two widely used programming languages, each with strengths and weaknesses. Both programming languages serve distinct purposes. The main difference between C and Java is that C...read more
What is Wrapper Class in Java?
What is Wrapper Class in Java?
This article will teach you what is wrapper class and how wrapper objects are created. It will also teach you the concept of autoboxing and unboxing in java.
Difference between Abstract class and Interface in Java
Difference between Abstract class and Interface in Java
Both abstract class and interface in java helps in achieving abstraction. They are similar in nature yet differ from each other when it comes to their usage. Let’s see what...read more

Creation of Thread

A thread behaves like a worker who works upon certain jobs. A thread always needs a target job to work upon. A job performed by the thread can be created using one of the below approaches:

  1. Implementing a runnable interface
  2. Extending thread class

Let’s see an example to understand a thread’s execution.

Example:

 
class job1 implements Runnable
{
public void run()
{
System.out.println("I am a job created by implementing runnable interface");
}
}
class job2 extends Thread
{
public void run()
{
System.out.println("I am a job created by extending thread class which implements runnable interface");
}
}
class Main {
public static void main(String[] args) {
job1 j1 = new job1();
Thread jobRunner = new Thread(j1);
jobRunner.start();
job2 j2 = new job2();
Thread jobRunner2 = new Thread(j2);
jobRunner2.start();
}
}
Copy code

Explanation:

Here, the threads jobRunner1 and jobRunner2 work upon the jobs instance j1 and j2 respectively.

Output:

output1

Also, read: Strings in Java

Creating Multiple Threads

In the above section, we saw multiple threads working on different jobs. This section shows the behavior when multiple threads work on the same job.

Example:

 
class job1 implements Runnable
{
public void run()
{
try
{
System.out.println("{This is child thread ");
Thread.sleep(500); //child thread sleeping
System.out.println("Running!}");
}
catch (InterruptedException e)
{
System.out.println(e);
}
}
}
class Main {
public static void main(String[] args) {
job1 j1 = new job1(); //creating job1 instance
Thread jobRunner = new Thread(j1); //thread1 assigned to job1 instance
jobRunner.start();
Thread jobRunner2 = new Thread(j1); //thread2 assigned to job1 instance
jobRunner2.start();
}
}
Copy code

Explanation:

The program demonstrates the creation of two threads working upon the same job named j1, an instance of job1 class. Here, we have three threads working simultaneously, main, jobRunner1, and jobRunner2. As they are working upon the same Runnable instance j1, their order of execution is not synchronized yet. Hence, results in garbled output.

Output:

output2

Read: Implementing Array in Java.

Conclusion

I hope the above article helped you better portray multithreading in the Java concept. Multithreading is an essential and crucial topic in concurrency, synchronization, and interthread communication. We’ll cover these topics in an upcoming article. Share your queries with us at the link below, and keep learning.

For more, Read: 8 Most Important Data Structures a Programmer Must Know 

About the Author

This is a collection of insightful articles from domain experts in the fields of Cloud Computing, DevOps, AWS, Data Science, Machine Learning, AI, and Natural Language Processing. The range of topics caters to upski... Read Full Bio