Java并发基石:线程生命周期与状态
Java 线程生命周期包含 6 种标准状态(java.lang.Thread.State):NEW → RUNNABLE →(BLOCKED / WAITING / TIMED_WAITING)→ TERMINATED。
✅ 核心速览:
- Java 线程生命周期包含 6 种标准状态(
java.lang.Thread.State):NEW→RUNNABLE→(BLOCKED/WAITING/TIMED_WAITING)→TERMINATED。 - 任意时刻,线程仅处于一种状态;这些是 JVM 逻辑状态,不等同于操作系统线程状态。
- 虚拟线程(JDK 21+)与平台线程共享完全相同的状态模型,但阻塞行为更高效:可自动卸载载体线程,避免 OS 线程浪费。
- 关键区别:
BLOCKED:仅由竞争synchronizedmonitor 锁引起;WAITING/TIMED_WAITING:由wait()、join()、sleep()、LockSupport.park()等主动等待操作触发;- 显式锁(如
ReentrantLock)不会导致BLOCKED,而是进入WAITING或TIMED_WAITING。
- 终止线程应使用协作式中断(
interrupt()),禁用已废弃的stop()(会导致资源/锁泄漏)。
Java 线程的生命周期描述了一个线程从创建到销毁所经历的各个状态。自 Java 5 引入 java.lang.Thread.State 枚举以来,线程状态模型已标准化,并在后续 JDK 版本(包括 JDK 21)中保持稳定。
值得注意的是,尽管 JDK 21 引入了虚拟线程(Virtual Threads),其生命周期状态模型与平台线程(Platform Threads)完全一致,均遵循以下六种状态:
NEW(新建)RUNNABLE(可运行 / 运行)BLOCKED(阻塞)WAITING(无时限等待)TIMED_WAITING(有时限等待)TERMINATED(终止)
这些状态在 java.lang.Thread.State 枚举中有明确定义,且 一个线程在任意时刻只能处于其中一种状态。这些是 JVM 层面的逻辑状态,不直接对应操作系统线程状态。
在操作系统层面,
BLOCKED、WAITING和TIMED_WAITING通常可视为“休眠状态”——处于这些状态的线程不会获得 CPU 使用权。
1、NEW(新建)
线程对象已被创建(通过 new Thread()),但 尚未调用 start() 方法。
- 线程未被 JVM 调度;
- 不占用系统线程资源(对虚拟线程而言,也尚未被调度器注册)。
Thread t = new Thread(() -> {});
// t.getState() == Thread.State.NEW
2、RUNNABLE(可运行 / 运行)
线程已调用 start(),处于 就绪(等待 CPU 时间片)或运行(正在 CPU 上执行) 状态。
- JVM 将这两种情况统一归为
RUNNABLE; - 应用层无法区分,切换由操作系统调度器处理;
- 对于虚拟线程:当有工作且未被阻塞时,也处于此状态,等待载体平台线程执行。
即使线程正在执行 I/O(如 System.in.read()),只要未被 JVM 识别为‘可卸载阻塞’,平台线程仍处于 RUNNABLE,但实际在 OS 层可能阻塞。
3、BLOCKED(阻塞)
线程正在 等待 monitor 锁,以便进入 synchronized 块或方法,或在 Object.wait() 后重新进入同步块。
- 触发场景:尝试获取已被其他线程持有的
synchronized锁; - 一旦锁被释放,JVM 会从阻塞队列中唤醒线程竞争锁;
- 仅适用于
synchronized锁; - 使用
ReentrantLock等显式锁导致的等待,线程会进入WAITING或TIMED_WAITING,而非BLOCKED。
4、WAITING(无时限等待)
线程主动放弃 CPU,进入无限期等待,直到被其他线程显式唤醒。
常见触发方法:
Object.wait()(无超时)Thread.join()(无超时)LockSupport.park()
唤醒方式:
Object.notify()/Object.notifyAll()- 被
join()的线程终止 LockSupport.unpark(thread)
流转图
RUNNABLE
→ (enter synchronized) → holds lock
→ Object.wait() → releases lock → WAITING
→ notify() → tries to reacquire lock → BLOCKED
→ acquires lock → RUNNABLE
5、TIMED_WAITING(有时限等待)
线程等待指定时间后自动唤醒,也可被提前唤醒。是 WAITING 的超时版本,用于实现定时、超时控制等。
触发方法:
Thread.sleep(long millis)Object.wait(long timeout)Thread.join(long millis)LockSupport.parkNanos(long nanos)LockSupport.parkUntil(long deadline)
6、TERMINATED(终止)
线程已完成执行(run() 正常结束)或因未捕获异常而终止。
- 一旦进入此状态,无法重启;
- 再次调用
start()会抛出IllegalThreadStateException。
7、虚拟线程(JDK 21+)
Project Loom 引入的虚拟线程在生命周期状态上完全兼容上述六种状态。
- 调用
Thread.start()后进入RUNNABLE; - 执行 I/O、
synchronized、LockSupport.park()等操作时,会进入BLOCKED、WAITING或TIMED_WAITING; - 关键区别:
- 平台线程:阻塞(如 I/O)会阻塞底层 OS 线程;
- 虚拟线程:遇到可卸载的阻塞操作(如多数 I/O),JVM 会自动释放载体平台线程,使其执行其他虚拟线程,从而实现高并发;
- 状态转换语义与平台线程完全一致。
彩蛋:stop() 和 interrupt()
| 方法 | 描述 |
|---|---|
stop() |
已废弃。直接强制终止线程,不释放锁(如 ReentrantLock),可能导致其他线程永久无法获取锁,引发死锁或数据不一致。类似方法 suspend() / resume() 同样不安全,不应使用。 |
interrupt() |
推荐方式。仅发送中断信号,线程可选择: - 通过 InterruptedException 响应(如 sleep()、wait());- 主动检查 Thread.interrupted() 或 isInterrupted();- 忽略中断(但不符合协作式中断规范)。 这是一种协作式中断机制,保证资源清理与状态一致性。 |
更多推荐



所有评论(0)