Java线程的6种状态是NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING、TERMINATED;其中RUNNABLE涵盖操作系统层面的就绪和运行两种状态,JVM未单独定义RUNNING枚举值,而是将其统一归入RUNNABLE。

Java 线程的生命周期中,NEW、RUNNABLE 和 RUNNING 并非完全独立的三个并列状态——JVM 官方定义只有 6 种状态,其中 RUNNING 并不作为 Thread.State 的枚举值存在。它属于操作系统层面的概念,而 JVM 将“就绪”和“正在执行”统一归为 RUNNABLE 状态。理解这一点,是避免状态认知偏差的关键。
NEW 状态:线程对象已建,但尚未启动
调用 new Thread(...) 后,线程仅是一个普通 Java 对象,JVM 已为其分配内存、初始化字段,但未关联任何 OS 线程资源,也未进入调度队列。
- 此时调用
thread.getState()返回Thread.State.NEW - 该状态只能通过调用
start()进入 RUNNABLE;不能重复 start,否则抛IllegalThreadStateException - 尚未开始执行
run()方法,也不涉及任何 CPU 调度或锁竞争
RUNNABLE 状态:具备执行资格,等待或正在运行
RUNNABLE 是 JVM 中最常观察到的状态,它涵盖两种操作系统行为:就绪(Ready)(等待 CPU 时间片)和 运行(Running)(正在 CPU 上执行)。JVM 不区分二者,统一视为 RUNNABLE。
- 调用
start()后立即进入此状态,无论是否已被 CPU 调度 - 线程可能正在执行计算、IO 等待(非阻塞式)、或空转循环,只要没主动让出 CPU 或被挂起,就保持 RUNNABLE
- 常见误区:sleep()、wait()、join()、synchronized 竞争失败等操作都会使线程离开 RUNNABLE,进入 TIMED_WAITING、WAITING 或 BLOCKED
- 即使 run() 方法已开始执行,只要还没结束,且未进入任何等待/阻塞逻辑,状态仍是 RUNNABLE
为什么没有独立的 RUNNING 枚举?
JVM 设计上将线程调度细节抽象化,把“是否获得 CPU 执行权”这一瞬时、不可控、OS 依赖的行为,交由底层系统处理。对 Java 程序员而言,关注点在于“能否继续推进逻辑”,而非“此刻是否在 CPU 上跑”。因此:
立即学习“Java免费学习笔记(深入)”;
-
Thread.State枚举中无 RUNNING 值,只有 NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING、TERMINATED - 工具如 jstack、JMC 或
getState()返回的 RUNNABLE,既可能对应 OS 的 Running,也可能对应 Ready - 试图用状态判断“当前是否真在执行”不可靠;需结合线程栈、CPU 使用率、业务日志综合分析
实际调试建议
排查线程行为时,别执着于“它是不是 RUNNING”,而应聚焦于:
- 若长期卡在 RUNNABLE:检查是否 CPU 密集型任务未 yield,或陷入死循环
- 若预期执行却始终是 NEW:确认是否漏掉
start()调用 - 若频繁进出 RUNNABLE → BLOCKED:用 jstack 查看锁持有者,定位 synchronized 竞争热点
- 若 RUNNABLE 后突然消失:检查是否异常退出(未捕获 Exception)导致静默终止


















