java线程6种状态是jvm对执行意图与资源占用的抽象:new(未start)、runnable(就绪或运行)、blocked(等锁)、waiting/timed_waiting(主动等待唤醒)、terminated(终结)。

Java 中线程的 6 种状态(NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING、TERMINATED)不是独立存在的标签,而是 JVM 对线程生命周期中不同执行意图和资源占用情况的抽象刻画。理解它们的关键不在于死记状态名,而在于抓住“线程此刻想干什么”和“它卡在哪儿了”。
NEW 状态:线程对象已诞生,但还没被 JVM 接纳
仅调用 new Thread(),未调用 start() —— 此时线程只是堆里一个普通对象,JVM 没给它分配栈空间,也不参与调度。它甚至没真正“出生”,只是有了名字和躯壳。
- 调用
thread.getState()返回NEW - 不能直接调用
run()来“启动”,那只是普通方法调用,不会开启新线程 - 只有调用
start()后,JVM 才为其创建系统级线程、分配栈,并将其纳入调度范围
RUNNABLE 状态:线程已上线,但不等于正在 CPU 上跑
这是最容易误解的状态。“RUNNABLE” 在 Java 层面指线程**已准备好运行或正在运行**,涵盖操作系统层面的“就绪(Ready)”和“运行(Running)”两种情况。JVM 不区分这两者,统一归为 RUNNABLE。
- BIO 场景下,线程正阻塞在 socket.read() 上,
getState()仍返回RUNNABLE—— 因为 JVM 认为它“可运行”,只是底层 OS 把它挂起了 - 调用
Thread.yield()后,线程仍处于 RUNNABLE,只是主动让出 CPU 时间片,等待下一次调度 - 只要没进入锁竞争、没显式等待、没休眠,绝大多数活跃线程都处于此状态
BLOCKED 状态:线程在门口排队,等一把锁
线程已进入 synchronized 代码块或方法的临界区入口,但目标锁被其他线程持有,只能暂停执行、进入锁池等待。此时它不消耗 CPU,也不持有任何锁(除了可能已持有的其他锁)。
- 只由 synchronized 触发;ReentrantLock 的
lock()不会导致 BLOCKED,而是抛出 InterruptedException 或自旋/排队,对应的是WAITING或TIMED_WAITING - 一旦持有锁的线程退出同步块并释放锁,JVM 会从锁池中随机唤醒一个 BLOCKED 线程,使其回到 RUNNABLE
- 注意:BLOCKED 是“争不到锁”,不是“等别人通知”——后者属于 WAITING
WAITING 和 TIMED_WAITING:线程主动让渡控制权,等别人喊它
这两个状态本质相同,区别只在“有没有时间限制”:
-
WAITING:调用Object.wait()(无参)、Thread.join()(无参)、LockSupport.park()后进入。必须依赖其他线程显式唤醒(notify()/notifyAll()、被 join 的线程结束、unpark()) -
TIMED_WAITING:调用Thread.sleep(ms)、Object.wait(ms)、Thread.join(ms)、LockSupport.parkNanos()等带超时的方法后进入。时间一到自动唤醒,或被提前唤醒 - 共同点:都已**释放当前持有的 monitor 锁**(
wait()必须在 synchronized 内调用),且不参与 CPU 竞争
TERMINATED 状态:线程使命完成,不可复活
线程的 run() 方法正常执行完毕,或因未捕获异常而退出,或被 stop()(已废弃)强制终止 —— 此时线程生命周期终结,JVM 回收其资源。
- 一旦进入 TERMINATED,
getState()始终返回该值,再次调用start()会抛出IllegalThreadStateException - 注意:
interrupt()不会让线程直接终止,它只是设置中断标志;是否响应、如何响应,完全由线程自身逻辑决定 - 没有“暂停后恢复”的状态,suspend/resume 已废弃,不安全也不可控
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











