For working professionals
For fresh graduates
More
Talk to our experts. We are available 7 days a week, 9 AM to 12 AM (midnight)
Indian Nationals
Foreign Nationals
The above statistics depend on various factors and individual results may vary. Past performance is no guarantee of future results.
The student assumes full responsibility for all expenses associated with visas, travel, & related costs. upGrad does not .
Recommended Programs
6. JDK in Java
7. C++ Vs Java
16. Java If-else
18. Loops in Java
20. For Loop in Java
46. Packages in Java
53. Java Collection
56. Generics In Java
57. Java Interfaces
60. Streams in Java
63. Thread in Java
67. Deadlock in Java
74. Applet in Java
75. Java Swing
76. Java Frameworks
78. JUnit Testing
81. Jar file in Java
82. Java Clean Code
86. Java 8 features
87. String in Java
93. HashMap in Java
98. Enum in Java
101. Hashcode in Java
105. Linked List in Java
109. Array Length in Java
111. Split in java
112. Map In Java
115. HashSet in Java
118. DateFormat in Java
121. Java List Size
122. Java APIs
128. Identifiers in Java
130. Set in Java
132. Try Catch in Java
133. Bubble Sort in Java
135. Queue in Java
142. Jagged Array in Java
144. Java String Format
145. Replace in Java
146. charAt() in Java
147. CompareTo in Java
151. parseInt in Java
153. Abstraction in Java
154. String Input in Java
156. instanceof in Java
157. Math Floor in Java
158. Selection Sort Java
159. int to char in Java
164. Deque in Java
172. Trim in Java
173. RxJava
174. Recursion in Java
175. HashSet Java
177. Square Root in Java
190. Javafx
he Thread Lifecycle in Java is a core concept in multithreading that defines how a thread progresses through different stages during its execution. Each state, New, Runnable, Running, Waiting, Timed Waiting, and Terminated, represents a specific phase in a thread’s existence, helping developers manage concurrency effectively. Understanding these stages is essential for writing efficient, responsive, and stable Java applications.
In this blog, we will explore the complete Thread Lifecycle in Java with clear explanations, diagrams, and practical examples. You will learn how threads transition between states, how lifecycle methods like start(), run(), and sleep() impact execution, and how to implement these concepts in real-world programs. By the end, you’ll have a strong foundation in Java multithreading.
Want to go further than just development? These industry-focused Software Engineering Courses are tailored to boost your skills and open doors to exciting career prospects.
Threads, the smallest unit of a process, follow a structured progression called the lifecycle and states of a thread in Java. This lifecycle includes six main states that a thread can occupy at any point in time:
1. New
A thread is in this state when you've created an instance of the Thread class but haven't invoked the start() method yet. It remains in this state until the program starts the thread.
Shape your tech career with in-demand skills in Cloud, DevOps, AI, and Full Stack Development. Gain hands-on experience through projects, guided by leading industry experts, and build the expertise top employers value worldwide.
2. Active
This state consists of two sub-states, Runnable and Running. Runnable implies that the thread is ready for execution and is waiting for resource allocation by the thread scheduler. Running means the thread scheduler has selected the thread and is currently executing its run() method.
3. Blocked / Waiting
A thread enters this state when it is temporarily inactive and waiting for a signal to proceed due to reasons like waiting for a resource to become available (Blocked) or waiting for another thread to perform a specific action (Waiting).
4. Timed Waiting
In this state, a thread is waiting for a specified period. A thread might enter this state through methods like Thread.sleep(long millis) or Object.wait(long timeout) where it waits for a particular duration before resuming its activities.
5. Terminated
This is the final state in the thread life cycle. The thread arrives here when it has completed its execution, i.e., its run() method has been completed, or it has been abruptly terminated due to an unhandled exception. Once in this state, the thread cannot be resumed.
As Java developers, having a profound understanding of these states and the transitioning nuances between them provides us with the power to harness threads effectively, optimizing the execution of our concurrent programs.
Let's go through a simple example to better understand the lifecycle of a thread in Java. In this example, let’s create a simple thread and explain the states it goes through in its lifecycle.
public class ThreadExample extends Thread {
@Override
public void run() {
for (int i = 0; i < 3; i++) {
try {
Thread.sleep(1000);
System.out.println("Thread running " + i);
} catch (InterruptedException e) {
System.out.println("Thread interrupted");
}
}
System.out.println("Thread execution completed");
}
public static void main(String[] args) {
ThreadExample te = new ThreadExample();
te.start();
}
}
The code creates a subclass of Thread called ThreadExample and overrides its run() method. Inside the run() method, there is a loop that runs three times, with a sleep interval of 1 second (1000 milliseconds) between each run. If the thread is interrupted during its sleep, it catches the InterruptedException and prints "Thread interrupted". After the loop completes its three runs, it prints "Thread execution completed."
In the main() method, an instance of ThreadExample is created and started, causing its run() method to execute in a separate thread.
The output of this program would look something like this:
Thread running 0
Thread running 1
Thread running 2
Thread execution completed
Let's walk through the stages this thread will go through:
By observing this simple example, we can see the thread moving through each state in its lifecycle: New, Active (Runnable and Running), Timed Waiting, and finally, Terminated.
Applets in Java also have a distinct lifecycle, much like threads, governed by a set of specific methods. The lifecycle consists of the following stages:
Let's delve into each of these stages:
1. Initialization
This is the first phase of the lifecycle. When an applet is loaded into the browser, the ‘init()’ method is called. This method is executed only once during the lifecycle of the applet. This method is used to perform one-time operations such as loading images or sounds, initializing variables, etc.
public void init() {
// Initialization code goes here
}
2. Starting
After initialization, the applet enters the Starting stage. The ‘start()’ method is called, signaling the applet to start its execution. This method is called every time an applet's webpage is opened or revisited, or when the applet is deiconified.
public void start() {
// Start or resume execution
}
3. Stopping
When a user navigates away from the webpage containing the applet, or the webpage is minimized, the ‘stop()’ method is called. This method allows you to suspend tasks that don't need to run when the applet is not visible.
public void stop() {
// Suspend execution
}
4. Destruction
This is the final stage of the applet's lifecycle. The ‘destroy()’ method is called when the browser closes, or the applet's webpage is no longer in use. This method gives the applet a chance to free up system resources and perform cleanup tasks.
Remember
Each stage can be overridden as per the need of the applet to execute specific tasks at each stage of the lifecycle. By understanding these stages, developers can control an applet's behavior throughout its existence in a web browser.
Also Read: How to Code, Compile, and Run Java Projects: A Beginner’s Guide
In Java, understanding the thread states is key for effective multithreading. Let's explore each of these thread states in Java with some examples:
1. New: A thread is in the new state when an instance of the Thread class gets created but the ‘start()’ method is not invoked yet.
Thread thread = new Thread(); // At this point, the thread is in the New state
2. Runnable: The thread transitions to the Runnable state when the ‘start()’ method is invoked. The thread might not be executed immediately but is ready for execution.
thread.start(); // The thread is now in the Runnable state
3. Running: The thread scheduler picks a thread from the pool of Runnable threads and moves it to the Running state where the thread's ‘run()’ method executes.
public void run() {
// Implementation of the thread's tasks
}
4. Blocked/Waiting: A thread enters this state when it is waiting for a resource, like I/O completion, and cannot proceed until it gets that resource or if it's waiting for another thread to perform a specific action.
synchronized(object) {
// The thread enters the Blocked state when it is waiting to acquire the lock on the object.
}
5. Timed Waiting: A thread enters this state when it calls methods like ‘Thread.sleep(long millis)’ or ‘Object.wait(long timeout)’, i.e., it's in a sleeping or waiting state for a specified period.
try {
Thread.sleep(2000); // The thread is in Timed Waiting state for 2 seconds
} catch (InterruptedException e) {
e.printStackTrace();
}
6. Terminated: The thread enters the Terminated state when it has completed its execution, i.e., its ‘run()’ method has been completed, or it has been abruptly terminated due to an unhandled exception.
public void run() {
// When the code in this method has finished running, the thread moves to the Terminated state
}
In these examples, we have implemented and observed the thread states in Java. Remember, managing these states effectively is pivotal for writing efficient multithreaded programs in Java.
Here is a Java program demonstrating thread states using thread methods in Java, with priority setting and creating threads in Java:
class ThreadDemo extends Thread {
// Overriding the run method
@Override
public void run() {
// loop to mimic some work
for(int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getId() + " Value " + i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Main {
public static void main(String args[]) {
// creating threads in Java
ThreadDemo t1 = new ThreadDemo();
ThreadDemo t2 = new ThreadDemo();
ThreadDemo t3 = new ThreadDemo();
// thread t1 starts
t1.start();
// thread methods in Java - setting priority of t2 to max (10)
t2.setPriority(Thread.MAX_PRIORITY);
t2.start();
// checking if t1 is alive
System.out.println("Is thread t1 alive? " + t1.isAlive());
// waiting for t1 to die
try {
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
// thread t3 starts
t3.start();
// thread priority in Java - setting priority of t3 to min (1)
t3.setPriority(Thread.MIN_PRIORITY);
// checking if t1 is alive
System.out.println("Is thread t1 alive? " + t1.isAlive());
}
}
In this program, we've created three threads, t1, t2, and t3, demonstrating the creation of threads in Java. The thread methods in Java are showcased via the ‘start()’, ‘setPriority()’, ‘isAlive()’, and ‘join()’ methods.
The thread t2's priority is set to MAX_PRIORITY, and t3's to MIN_PRIORITY, demonstrating thread priority in Java.
Code Explanation:
The code defines a class ThreadDemo that extends the Thread class in Java. Inside this class, the run() method is overridden. The run() method is where the execution of a new thread starts after the start() method is called.
In the run() method, there's a for-loop that runs five times. Inside the loop, Thread.sleep(1000) makes the current thread sleep for 1 second (or 1000 milliseconds). The program then prints the ID of the current thread and the value of i. If the thread is interrupted while sleeping, an InterruptedException is caught and its stack trace is printed.
The main() method in the Main class is where the program starts execution. Three ThreadDemo objects, t1, t2, and t3, are created, illustrating creating threads in Java.
t1 is started with t1.start(), which causes the run() method in t1 to begin execution in a new thread.
t2 is given maximum priority using setPriority(Thread.MAX_PRIORITY), after which it is started. Thread priorities in Java range from 1 (minimum priority) to 10 (maximum priority), and they influence the order in which threads are scheduled to run.
The program then checks if t1 is still running (alive) with t1.isAlive() and prints the result.
Next, t1.join() is called, which causes the current thread (main thread) to pause execution until t1 has finished executing (is no longer alive).
T3 is then started and given minimum priority.
Finally, the program checks again whether t1 is still running and prints the result.
Example Output:
Thread-0 Value 0
Thread-1 Value 0
Is thread t1 alive? true
Thread-0 Value 1
Thread-1 Value 1
Thread-0 Value 2
Thread-1 Value 2
Thread-0 Value 3
Thread-1 Value 3
Thread-0 Value 4
Thread-1 Value 4
Is thread t1 alive? false
Thread-2 Value 0
Thread-2 Value 1
Thread-2 Value 2
Thread-2 Value 3
Thread-2 Value 4
This program presents a solid example of the lifecycle and states of a thread in Java, demonstrating thread methods, thread creation, and thread priority in action. Each thread transitions between the various states (New, Runnable, Timed Waiting, and Terminated) during the course of execution.
Understanding the Thread Lifecycle in Java is essential for creating reliable and efficient multithreaded applications. The lifecycle and states of a thread in Java, New, Runnable, Running, Blocked, Waiting, Timed Waiting, and Terminated, represent distinct phases that govern how a thread operates within a program. By applying methods like start(), run(), sleep(), and join(), developers can manage these transitions with precision.
Proper handling of threads enhances application responsiveness, ensures better resource utilization, and supports concurrent execution. Additionally, considering synchronization and thread safety prevents issues such as race conditions or deadlocks. A solid grasp of the thread lifecycle empowers Java developers to design high-performing applications that run smoothly in real scenarios.
The Thread Lifecycle in Java directly affects performance by managing how threads start, run, wait, and terminate. Proper lifecycle management ensures optimal CPU utilization, reduces idle time, and minimizes resource conflicts. By understanding these states, developers can create responsive and efficient Java applications that scale better under heavy workloads.
A clear understanding of the Thread Lifecycle in Java helps detect issues like race conditions and deadlocks. By knowing which state a thread is in, developers can analyze thread behavior and troubleshoot errors effectively. This knowledge improves debugging efficiency and ensures smoother execution of multithreaded programs.
Thread synchronization is essential in the lifecycle and states of a thread in Java. It prevents multiple threads from accessing shared resources simultaneously. Synchronization directly impacts the Blocked and Waiting states, ensuring thread safety, data consistency, and preventing deadlocks when threads compete for the same resource.
The Thread Lifecycle in Java defines six distinct states: New, Runnable, Running, Waiting, Timed Waiting, and Terminated. While other languages may follow similar principles, the terminology and state transitions differ. Java’s structured lifecycle gives developers precise control over concurrency and thread management compared to other programming languages.
The lifecycle and states of a thread in Java include New, Runnable, Running, Waiting, Timed Waiting, and Terminated. Each state represents a specific execution stage. Understanding these states allows developers to track thread behavior, manage concurrency, and ensure stable and efficient application performance.
In the New state, a thread object is created but has not started execution. This stage allows developers to initialize resources, assign priorities, or configure properties before the thread begins. Once the start() method is invoked, the thread transitions to the Runnable state, awaiting CPU allocation.
In the Runnable state, the thread is eligible for execution but awaits CPU scheduling. Multiple threads may exist in this state simultaneously. The thread scheduler decides which thread moves to the Running state. This phase is crucial for concurrency and resource sharing in multithreaded applications.
In the Waiting state, a thread pauses indefinitely until another thread signals it to resume. In contrast, the Timed Waiting state allows a thread to pause for a defined time using methods like sleep() or join(timeout). Both states help manage thread coordination and resource usage.
A thread enters the Terminated state once its execution completes. At this stage, the thread cannot be restarted, and attempts to do so result in IllegalThreadStateException. This state signifies the end of the thread’s lifecycle and ensures resources are released for system efficiency.
No, once a thread reaches the Terminated state, it cannot return to any previous state. To execute the same task again, developers must create a new thread instance. This restriction maintains lifecycle integrity and prevents unexpected program behavior in Java multithreading.
Understanding the lifecycle and states of a thread in Java ensures efficient concurrency management. Developers can optimize CPU usage, prevent deadlocks, and improve response time. This knowledge helps build stable and scalable multithreaded applications that function effectively under varying loads.
Common methods include start(), run(), sleep(), wait(), notify(), join(), and yield(). These methods control transitions between states in the Thread Lifecycle in Java. Using them effectively allows developers to manage concurrency, scheduling, and synchronization across multiple threads.
The thread scheduler determines which thread in the Runnable pool enters the Running state. Its decision depends on the JVM implementation and the operating system. Since scheduling is non-deterministic, developers cannot control the exact execution order, making lifecycle understanding essential.
The start() method transitions a thread from the New state to the Runnable state. This method signals the JVM to schedule the thread for execution. Without invoking start(), the thread remains inactive and never participates in the Thread Lifecycle in Java.
If run() is called directly, it behaves like a normal method and executes within the current thread. No new thread is created, and the Thread Lifecycle in Java is bypassed. To create a new concurrent thread, the start() method must be used.
Thread priority provides hints to the scheduler about which thread should run first. Higher-priority threads are generally executed sooner. However, exact execution order depends on the JVM and OS. Priorities impact the Runnable state but do not guarantee strict control.
The most common exceptions are InterruptedException, which occurs when a waiting or sleeping thread is interrupted, and IllegalThreadStateException, raised when attempting to restart a terminated thread. These exceptions highlight the importance of understanding lifecycle rules in Java multithreading.
By knowing the states in which threads may block or wait, developers can design synchronization strategies that avoid circular waits and resource conflicts. Understanding the lifecycle helps prevent deadlocks by ensuring proper thread coordination and resource allocation.
Developers can use Java VisualVM, JConsole, or thread dumps to monitor the lifecycle and states of a thread in Java. These tools provide real-time insights into thread states, helping identify performance issues, deadlocks, and inefficient resource usage.
Mastering the lifecycle and states of a thread in Java allows developers to design efficient, concurrent applications. It improves resource management, prevents synchronization issues, and ensures responsive performance. This knowledge is crucial for building scalable, high-performance Java systems.
Take the Free Quiz on Java
Answer quick questions and assess your Java knowledge
FREE COURSES
Start Learning For Free
Author|900 articles published