Understanding Thread States (Thread Life Cycle) in Java
- Details
- Written by Nam Ha Minh
- Last Updated on 12 August 2019   |   Print Email
This Java Thread tutorial helps you understand the life cycle of a thread with illustrated diagram and code example.
A thread can go through various states during its life. The Thread’s getState() method returns an enum constant that indicates current state of the thread, which falls in one of the following values:
- RUNNABLE
- BLOCKED
- WAITING
- TIMED_WAITING
- TERMINATED
These enum constants are defined in the Thread.State enum. Let me explain each state in details.
- NEW: when a thread is created but has not executed (the start() method has not been invoked), it is in the new state.
- RUNNABLE: when the start() method has been invoked, the thread enters the runnable state, and its run() method is executing. Note that the thread can come back to runnable state from another state (waiting, blocked), but it may not be picked immediately by the thread scheduler, hence the term “runnable”, not running.
- BLOCKED: when a thread tries to acquire an intrinsic lock (not a lock in the java.util.concurrent package) that is currently held by another thread, it becomes blocked. When all other threads have relinquished the lock and the thread scheduler has allowed this thread to hold the lock, the thread becomes unblocked and enters the runnable state.
- WAITING: a thread enters this state if it waits to be notified by another thread, which is the result of calling Object.wait() or Thread.join(). The thread also enters waiting state if it waits for a Lock or Condition in the java.util.concurrent package. When another thread calls Object‘s notify()/notifyAll() or Condition’s signal()/signalAll(), the thread comes back to the runnable state.
- TIMED_WAITING: a thread enters this state if a method with timeout parameter is called: sleep(), wait(), join(), Lock.tryLock() and Condition.await(). The thread exits this state if the timeout expires or the appropriate notification has been received.
- TERMINATED: a thread enters terminated state when it has completed execution. The thread terminates for one of two reasons:
+ the run() method exits normally.
+ the run() method exits abruptly due to a uncaught exception occurs.
The following diagram helps you visually understand the thread states and transitions between them:
And the following code example illustrates how to check state of a thread:
public class ThreadState { public static void main(String[] args) throws InterruptedException { Thread t = new Thread(new Runnable() { public void run() { Thread self = Thread.currentThread(); System.out.println(self.getName() + "is " + self.getState());// LINE 0 } }); System.out.println(t.getName() + "is " + t.getState()); // LINE 1 t.start(); t.join(); if (t.getState() == Thread.State.TERMINATED) { System.out.println(t.getName() + " is terminated"); // LINE 2 } } }
Run this program and you will see the following output:
Thread-0 is NEW Thread-0 is RUNNABLE Thread-0 is terminated
Line 1 prints Thread-0 is NEW because at this time the thread t has not been started.
When the thread started, its run method execute, hence line 0 prints Thread-0 is RUNNABLE.
The call t.join() causes the main thread to wait for the thread t to finish, hence line 2 is always executed after thread t completes, thus the output Thread-0 is terminated.
Note that the thread’s state may change after the call to getState(). That means calling getState() may not reflect the actual state of the thread only a moment later.
API References:
Related Java Thread Tutorials:
- How to use Threads in Java (create, start, pause, interrupt and join)
- How to list all threads currently running in Java
- Understanding Thread Priorities and Daemon Thread in Java
- Understanding Thread Group in Java
Other Java Concurrency Tutorials:
- Java Synchronization Tutorial
- Understanding Deadlock, Livelock and Starvation with Code Examples in Java
- Understanding Java Fork-Join Framework with Examples
- Understanding Java Thread Pool and Executors
Comments
Look at the code example again, the line that prints RUNNABLE is in the run() method of the Thread, which is executed after t.start() call.