Mastering Java Thread Lifecycle: From NEW to TERMINATED Explained
This article provides a comprehensive guide to Java's thread lifecycle, detailing each of the six thread states, their meanings, how they are triggered, and practical code examples that demonstrate state transitions and logging output.
Java Thread States
Java defines six distinct thread states that a Thread instance can occupy during its lifetime:
NEW – The thread has been created but not yet started.
RUNNABLE – The thread is ready to run or is currently executing.
BLOCKED – The thread is waiting to acquire a monitor lock.
WAITING – The thread is waiting indefinitely for another thread to perform a specific action.
TIMED_WAITING – The thread is waiting for a specified period before proceeding.
TERMINATED – The thread has completed execution.
The following diagram visualizes these states and their possible transitions:
Enum Definition in JDK
public enum State {
/** Thread state for a thread which has not yet started. */
NEW,
/** Thread state for a runnable thread. */
RUNNABLE,
/** Thread state for a thread blocked waiting for a monitor lock. */
BLOCKED,
/** Thread state for a waiting thread. */
WAITING,
/** Thread state for a waiting thread with a timeout. */
TIMED_WAITING,
/** Thread state for a terminated thread. */
TERMINATED;
}NEW State
A thread in the NEW state has been instantiated but not started.
public class NewThread implements Runnable {
public static void main(String[] args) {
Runnable runnable = new NewThread();
Thread t = new Thread(runnable);
log.info(t.getState().toString()); // prints NEW
}
@Override
public void run() {}
}RUNNABLE State
When a thread is ready to execute or is currently executing, it is in the RUNNABLE state.
public class RunnableThread implements Runnable {
@Override
public void run() {}
public static void main(String[] args) {
Runnable runnable = new RunnableThread();
Thread t = new Thread(runnable);
t.start();
log.info(t.getState().toString()); // prints RUNNABLE
}
}BLOCKED State
A thread enters BLOCKED when it attempts to acquire a monitor lock that another thread holds.
public class BlockThread implements Runnable {
@Override
public void run() { loopResource(); }
public static synchronized void loopResource() {
while (true) { /* infinite loop */ }
}
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new BlockThread());
Thread t2 = new Thread(new BlockThread());
t1.start();
t2.start();
Thread.sleep(1000);
log.info(t1.getState().toString()); // RUNNABLE
log.info(t2.getState().toString()); // BLOCKED
System.exit(0);
}
}WAITING State
A thread is in WAITING when it calls one of the following without a timeout: Object.wait(), Thread.join(), or LockSupport.park().
public class WaitThread implements Runnable {
public static Thread t1;
@Override
public void run() {
Thread t2 = new Thread(() -> {
try { Thread.sleep(10000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); }
log.info("t1" + t1.getState().toString());
});
t2.start();
try { t2.join(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); }
log.info("t2" + t2.getState().toString());
}
public static void main(String[] args) {
t1 = new Thread(new WaitThread());
t1.start();
}
}TIMED_WAITING State
The TIMED_WAITING state occurs when a thread waits for a specified period, such as via Thread.sleep(long), Object.wait(long), Thread.join(long), LockSupport.parkNanos, or LockSupport.parkUntil.
public class TimedWaitThread implements Runnable {
@Override
public void run() {
try { Thread.sleep(5000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); }
}
public static void main(String[] args) throws InterruptedException {
TimedWaitThread obj = new TimedWaitThread();
Thread t = new Thread(obj);
t.start();
Thread.sleep(1000);
log.info(t.getState().toString()); // prints TIMED_WAITING
}
}TERMINATED State
A thread reaches TERMINATED after its run() method finishes.
public class TerminatedThread implements Runnable {
@Override
public void run() {}
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(new TerminatedThread());
t.start();
Thread.sleep(1000);
log.info(t.getState().toString()); // prints TERMINATED
}
}Understanding these states helps developers diagnose concurrency issues, design proper synchronization, and write more predictable multithreaded Java applications.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
