Understanding Java Thread States and Their Transitions
This article explains Java thread lifecycle states, detailing the six JVM-defined states (NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED), their transitions, and the finer distinction between READY and RUNNING within the RUNNABLE state, while clarifying why Java does not define a separate RUNNING state.
In a multithreaded operating system, a process typically contains multiple threads, each of which is the basic unit of CPU utilization and incurs minimal overhead.
Threads have states defined in the Thread.State enum, as clearly explained in the Java documentation.
By examining the source code and the Java documentation, we can see that threads have six main states:
NEW : When a thread is created but start() has not yet been called, it is in the NEW state.
RUNNABLE : A thread that is executing in the Java Virtual Machine is in this state.
BLOCKED : A thread that is blocked waiting for a lock is in this state.
WAITING : A thread that is waiting indefinitely for another thread to perform a specific action, requiring a notification or interruption, is in this state.
TIMED_WAITING : A thread that waits for another thread to perform an action for a specified period of time; unlike WAITING, it can return automatically after the timeout.
TERMINATED : A thread that has completed execution is in this state.
At any given moment, a thread can be in only one state. Note that these states represent the JVM thread states, not the underlying operating‑system thread states.
Thread states can transition between each other, as shown in the diagram below:
The JVM defines the RUNNABLE state, but we can further refine it based on whether the thread has actually obtained CPU time. This yields two sub‑states:
READY : After a thread object is created and another thread (e.g., the main thread) calls its start() method, the thread resides in the runnable pool, waiting to be scheduled and allocated CPU time.
RUNNING : A READY thread that has been granted a CPU time slice and begins executing code.
Thus, after a thread is created and start() is invoked, it is in the READY state until it acquires a CPU time slice, at which point it becomes RUNNING.
Why is there no separate RUNNING state defined?
In modern time‑sharing operating systems with a single CPU, threads are executed serially, but the CPU time is divided into short slices (typically 10–20 ms) to give the illusion of concurrent execution. A thread may spend part of a second in READY and part in RUNNING.
If a distinct RUNNING state were defined, it would be imprecise because a thread that appears to be RUNNING might have just lost its time slice.
What matters is whether a thread is currently eligible to execute—i.e., it is in a state that can acquire a time slice. That is exactly what the RUNNABLE state represents, so Java does not define a separate RUNNING state.
Full-Stack Internet Architecture
Introducing full-stack Internet architecture technologies centered on Java
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.