如何将Thread线程状态描述为一个超?
摘要:线程的状态及状态转换全解析 Java 线程的状态是并发编程的基础,JDK 官方(java.lang.Thread.State 枚举)定义了6种核心状态,状态转换则围绕“线程生命周期”和“同步阻塞操作”展开。下面从「状态定义→转换规则→实战
线程的状态及状态转换全解析
Java 线程的状态是并发编程的基础,JDK 官方(java.lang.Thread.State 枚举)定义了6种核心状态,状态转换则围绕“线程生命周期”和“同步/阻塞操作”展开。下面从「状态定义→转换规则→实战示例」讲透这一核心知识点。
一、先明确:Java 线程的 6 种核心状态
Thread.State 枚举明确了线程的所有合法状态,每个状态对应线程生命周期的一个阶段,先看官方定义:
状态名称
核心含义
NEW(新建)
线程对象已创建,但未调用 start() 方法,未真正启动
RUNNABLE(可运行)
线程调用 start() 后进入该状态(包含「正在运行」和「等待CPU调度」两种子状态)
BLOCKED(阻塞)
线程因竞争对象锁(如 synchronized)被阻塞,等待获取锁
WAITING(等待)
线程无时限等待(需其他线程显式唤醒),如 Object.wait()、Thread.join()
TIMED_WAITING(计时等待)
线程有时间限制的等待,如 Thread.sleep(ms)、Object.wait(ms)
TERMINATED(终止)
线程执行完成(run() 方法结束)或异常终止,生命周期结束
注意:很多人会混淆「RUNNABLE 的子状态」—— RUNNABLE 包含“就绪(等待CPU)”和“运行(占用CPU)”,但 JDK 并未将其拆分为两个独立状态,统一归为 RUNNABLE。
二、核心:线程状态转换规则(附流程图)
线程的状态转换是“单向为主、部分双向”的,核心流转逻辑如下(用 Mermaid 可视化):
逐类拆解关键转换场景
1. NEW → RUNNABLE:唯一触发方式
只有调用线程的 start() 方法,才能让线程从“新建”进入“可运行”状态,且一个线程只能调用一次 start()(多次调用会抛出 IllegalThreadStateException)。
示例:
// NEW 状态:仅创建对象,未启动
Thread t = new Thread(() -> System.out.println("线程运行"));
System.out.println(t.getState()); // 输出:NEW
// 调用start(),进入RUNNABLE
t.start();
System.out.println(t.getState()); // 大概率输出:RUNNABLE(CPU调度可能有延迟)
2. RUNNABLE ↔ BLOCKED:仅与 synchronized 锁相关
只有竞争 synchronized 修饰的方法/代码块失败时,线程才会进入 BLOCKED 状态;一旦获取到锁,立即回到 RUNNABLE。
注意:Lock 锁(如 ReentrantLock)的等待不会进入 BLOCKED 状态,而是进入 WAITING/TIMED_WAITING(因为 Lock 基于 Condition 实现,底层调用 LockSupport.park())。
