Thread Life Cycle in Java

Introduction
By now, I hope you have a clear and concise understanding of threads and how we can create threads in Java. In this blog, we will discuss the lifecycle of a thread in Java. Yes, you read it correctly! A thread also has its own lifecycle, or we can say a thread can have different states, just like humans have different states (running, waiting, sleeping, etc.). Today, we will understand the lifecycle of a thread.
States of a Thread
From the creation of a thread to its execution and from execution to termination/completion, a thread transitions through different states. In Java, the Thread
class has a static enum called State
, where six different states are defined. At any point in its lifecycle, a thread can be in one of these six states:
NEW State
RUNNABLE State
WAITING State
TIMED_WAITING State
BLOCKED State
TERMINATED State
Let’s understand each state with code examples.
NEW State
This is the stage when a thread is created but has not yet started. If you remember from the thread creation blog, a thread will start executing code only after calling the start()
method. So, after defining or creating a thread, until we call the start()
method, that thread remains in its NEW state.
Example:
Runnable runnable = new NewState();
Thread t = new Thread(runnable);
System.out.println(t.getState());
In this code snippet, we have created a thread t
but haven’t called the start()
method yet. That’s why, when we call getState()
, it will return NEW
as the output.
RUNNABLE State
This state represents when a thread is ready to run or is already running (executing code), but it is waiting for system resource allocation. A thread moves from the NEW
state to the RUNNABLE
state when we create a thread and call the start()
method.
Example:
Runnable runnable = new NewState();
Thread t = new Thread(runnable);
t.start();
System.out.println(t.getState());
The above code snippet is most likely to return the output as RUNNABLE
.
Note: It is possible that the thread reaches a different state by the time control moves to the print statement, so we may get a different output.
WAITING State
In this state, a thread is waiting for another thread to complete a specific action. According to Java Docs, any thread can enter this state by calling one of the following methods:
Object.wait()
Thread.join()
LockSupport.park()
In the next blog, we will discuss the notify()
, notifyAll()
, and wait()
methods in more detail. For now, let's understand the WAITING
state with an example.
Example:
public class WaitingState implements Runnable {
public static Thread t1;
public static void main(String[] args) {
t1 = new Thread(new WaitingState());
t1.start();
}
public void run() {
Thread t2 = new Thread(new DemoWaitingStateRunnable());
t2.start();
try {
t2.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
e.printStackTrace();
}
}
}
class DemoWaitingStateRunnable implements Runnable {
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
e.printStackTrace();
}
System.out.println(WaitingState.t1.getState());
}
}
In this example, when we start thread t1
, it creates a new thread t2
, starts it, and then waits for t2
to complete its execution. This means t1
will only complete after t2
has finished execution. Since we are printing the state of t1
while t2
is running and t1
is waiting, the expected output is WAITING
.
TIMED_WAITING State
This is similar to the WAITING
state, but instead of waiting indefinitely, the thread waits for a specified period. According to Java Docs, a thread can enter the TIMED_WAITING
state in five ways:
Thread.sleep(long millis)
wait(int timeout)
orwait(int timeout, int nanos)
Thread.join(long millis)
LockSupport.parkNanos()
LockSupport.parkUntil()
Example:
public class TimedWaitingState {
public static void main(String[] args) throws InterruptedException {
DemoTimeWaitingRunnable runnable = new DemoTimeWaitingRunnable();
Thread t1 = new Thread(runnable);
t1.start();
// Giving enough time for ThreadScheduler to start processing t1
Thread.sleep(1000);
System.out.println(t1.getState());
}
}
class DemoTimeWaitingRunnable implements Runnable {
@Override
public void run() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
e.printStackTrace();
}
}
}
In the above code snippet, we are printing the state of thread t1
while it is in the sleep stage for 5 seconds, so the expected output will be TIMED_WAITING
.
BLOCKED State
If two threads attempt to execute the same synchronized code block, and one thread is already executing it, the second thread will be blocked until the first thread finishes. That means the second thread cannot access the synchronized block until the first one exits.
Example:
public class BlockedState {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new DemoBlockedRunnable());
Thread t2 = new Thread(new DemoBlockedRunnable());
t1.start();
t2.start();
Thread.sleep(1000);
System.out.println(t2.getState());
System.exit(0);
}
}
class DemoBlockedRunnable implements Runnable {
@Override
public void run() {
commonResource();
}
public static synchronized void commonResource() {
while (true) {
// Infinite loop to mimic heavy processing
}
}
}
Here, since t1
is already executing the synchronized commonResource()
method, t2
will not be able to enter and execute that method until t1
finishes. So the expected output will be BLOCKED
.
TERMINATED State
This state indicates that a thread has completed execution or was terminated abnormally.
Example:
public class TerminatedState implements Runnable {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new TerminatedState());
t1.start();
// Giving enough time for thread t1 to complete
Thread.sleep(1000);
System.out.println(t1.getState());
}
@Override
public void run() {
// No processing in this block
}
}
In this example, after calling start()
, the Thread.sleep(1000)
statement ensures enough time for t1
to complete execution. The expected output will be TERMINATED
.
Conclusion
These are all the states of a thread, explained with examples. I hope you have understood all the states well!
Subscribe to my newsletter
Read articles from Jayita Saha directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
