Multithreading Program in Java
Multithreading Program in Java: Before discussing multithreading, it is important to discuss threads. Threads are the most fundamental part of a process. A process can have one or more threads. The execution of one thread is independent of another thread. Thus, when some error/ exception is generated in one thread, it does not hamper the process of another thread. All threads of the same process share the same memory space. Multithreading is the process of handling more than one thread simultaneously. The multithreading program in Java demonstrates the usage/ implementation of multithreading in the programming world.
Purpose of Multithreading
Multithreading ensures the maximum utilization of the CPU time when a program is executed. If a program is required to complete more than one task, which is independent of each other, multithreading is required.
Different States of a Thread in Java
The different states of a Thread are:
- New: A thread whose execution has not started comes in this stage.
- Runnable: After the start() method is called, the thread is in the queue for processing and ready to run, i.e., the thread scheduler has not selected the thread to move it to the running state. In other words, threads in this stage are waiting for the CPU for execution.
- Running: The thread scheduler has moved the thread from runnable to this stage, which means the thread gets the CPU, and its execution is started. Note that the Runnable and Running stages form the active state of a thread.
- Blocked/ Waiting: A thread that is still alive but is not eligible to enter the active state. A thread may enter this stage if a high-priority thread intervenes.
- Dead/ Terminated: A thread that can no longer be used in a program. Usually, a thread enters this stage when the thread has completed its task or is forcefully terminated.
The following figure depicts the states of a thread.

Creating a Thread in Java
There are two ways to create thread in Java.
1) By inheriting the Thread class
2) By implementing the Runnable Interface
Let’s discuss each of these given ways.
By inheriting the Thread class
Thread class implements the Runnable interface. In the Runnable interface, there is a method called run() that is like the service method of the thread. We need to override it in our thread class. See the following example.
FileName: UserThreadExample.Java
// A class that inherits the class Thread class MyThread extends Thread { String m; int x; // constructor of the class public MyThread(String m) { this.m = m; x = 5; } // implemeting run() from // the Runnable interface public void run() { for(int i = 1; i <= x; i++) { System.out.println(m); } } } public class UserThreadExample { // driver method public static void main(String argvs[]) { MyThread t1 = new MyThread("Hello"); MyThread t2 = new MyThread("Hi"); MyThread t3 = new MyThread("Bye"); // invoking the method start() t1.start(); t2.start(); t3.start(); } }
Output:
Hello Bye Hi Hi Hi Hi Hi Bye Bye Bye Bye Hello Hello Hello Hello
Explanation: In the above code, we have created three threads. When the start() method is invoked, the thread enters in the active state. The start() method internally calls the run() method. A thread can never invoke the start() method more than once. If happens the same, it throws java.lang.IllegalThreadStateException is thrown. First, we have executed the threads t1, then t2, and finally t3. However, it does not guarantee that thread t1 is executed first. It is the duty of the thread scheduler to decide which thread will be executed first. We observe that four “Hello” are printing after “Bye”. If we execute our code again, it might happen we get different output. This is because context switching between the threads is not controlled by us.
Note: Every Java program has one thread called the main thread. The main thread is responsible for the execution of the main/ driver method. Thus, in the above example, there are 4 threads are executing.
By Implementation the Runnable Interface
FileName: UserThreadExample1.Java
// A class that implements the interface Runnable public class UserThreadExample1 implements Runnable { public void run() { System.out.println("Inside the method run ..."); } public static void main(String argvs[]) { // Creating an object of the class UserThreadExample1 UserThreadExample1 usrObj = new UserThreadExample1(); // Creating a thread t1 using the object usrObj Thread t1 =new Thread(usrObj); // starting the thread by invoking the start() method. t1.start(); } }
Output:
Inside the method run ...
Explanation: The Runnable interface contains only a method called run(). The object (usrObj) is of the class UserThreadExample1. The class UserThreadExample1 implements the interface Runnable. It does not contain the method start(). The start() method is present in the class Thread. Therefore, we have created a thread t1 using the object usrObj. Finally, using the thread t1, the method start() is invoked to being the execution of the thread.
Priorities of a Thread
The scheduling of a thread is determined with the help of its priorities by an operating system. The range of priorities varies between 1 – 10. The MIN_PRIORITY takes the constant value 1, and MAX_PRIORITY takes the constant value 10. NORM_PRIORITY, which takes the constant value 5, is the default priority of a thread in Java. A thread with a high priority value is more important as compared to a thread with a low priority value. Therefore, the processor time of the high priority thread is allocated first, whereas the allocation of processor time is done later for the low priority thread. Note that high/ low priority does not guarantee the order of execution of threads. The order of execution of threads is very much dependent on the platform.