java线程六种状态是jvm对os线程行为的语义封装:new和terminated不触发系统调用;runnable涵盖就绪与运行;blocked专等synchronized锁;waiting需显式唤醒;timed_waiting带超时自动恢复;所有转换均由特定方法调用驱动。

理解 Java 线程的六种状态,关键不是死记枚举值,而是看清每种状态背后真实的物理行为:CPU 是否在跑、内核是否介入、锁是否被占、内存与栈是否已分配。这六种状态是 JVM 对操作系统线程生命周期的语义封装,不是抽象概念,而是有明确底层映射的“行为快照”。
NEW 和 TERMINATED:纯 JVM 对象生命周期标记
这两个状态不触发任何系统调用,也不占用 OS 线程资源。
-
NEW:仅表示 Thread 对象已 new 出来,JVM 还没调用
pthread_create(Linux)或CreateThread(Windows)。此时没有栈、无寄存器上下文、不在任何调度队列里——就像填好但没投出的简历。 -
TERMINATED:run() 方法结束或抛出未捕获异常后,JVM 已释放栈内存、清空本地变量,并通知 OS 回收其内核结构(如 Linux 的
task_struct)。线程彻底退出调度,不可再 join 或 resume。
RUNNABLE:就绪 + 运行的统一视图
这是最易误解的状态。它不等于“正在 CPU 上执行”,而是指线程具备运行资格、且未被 Java 层阻塞机制挂起。
- 处于 RUNNABLE 的线程,可能正在 CPU 上运行(Running),也可能在 OS 就绪队列中排队(Ready)——取决于调度器是否分到时间片。
- yield()、时间片耗尽、轻量级上下文切换,都不会改变该状态;JVM 只保证:只要没进 BLOCKED/WAITING/TIMED_WAITING,就视为可调度。
- 底层对应的是 OS 内核线程处于 TASK_RUNNING 状态(Linux),即被纳入 CFS 调度队列,等待或正在获得 CPU。
BLOCKED / WAITING / TIMED_WAITING:三类阻塞,三种内核交互方式
它们都让出 CPU,但等待目标、唤醒机制和内核参与程度完全不同。
- BLOCKED:专等 synchronized monitor 锁。线程在 JVM 锁竞争队列中自旋或挂起,不进入 OS 睡眠态;锁一释放,JVM 立即将其重新入 OS 就绪队列,状态切回 RUNNABLE。
-
WAITING:主动挂起,需显式唤醒。例如调用
Object.wait()后,JVM 通过Unsafe.park()触发 futex 等待(Linux),线程真正进入内核睡眠队列;只有收到notify()或unpark()才被内核唤醒并回到 RUNNABLE。 -
TIMED_WAITING:带超时的 WAITING。内核层面启用定时器(如
clock_nanosleep),超时自动唤醒,或中途被 notify/unpark 中断,均返回 RUNNABLE。
状态转换不是随意跳转,而是受方法调用严格驱动
每种转换都有确定的入口点,且不可逆(NEW→TERMINATED 单向):
- NEW → RUNNABLE:调用
start(),JVM 发起系统调用创建内核线程。 - RUNNABLE → BLOCKED:尝试进入 synchronized 块/方法但锁被占用。
- RUNNABLE → WAITING:调用
wait()、join()、LockSupport.park()。 - RUNNABLE → TIMED_WAITING:调用
sleep()、wait(5000)、parkNanos()等。 - RUNNABLE / BLOCKED / WAITING / TIMED_WAITING → TERMINATED:run() 正常返回或抛出未捕获异常。











