start()方法驱动线程从NEW→RUNNABLE:先校验状态为0,再注册到ThreadGroup、调用start0()创建系统线程,最后标记为RUNNABLE;该状态仅表示具备运行资格,不保证立即执行,且不可重复调用。

Java 中 start() 方法的执行流程,本质上就是驱动线程从 NEW 状态进入 RUNNABLE 状态的关键过程,它严格遵循 Java 线程状态机的单向转换规则。
start() 触发的状态跃迁:NEW → RUNNABLE
每个 Thread 对象在构造完成但尚未调用 start() 时,处于 NEW 状态。此时线程尚未被 JVM 注册,也未关联任何系统级线程资源。
start() 方法内部会做一次原子性状态校验:
- 检查
threadStatus字段是否为 0(即 NEW); - 若不为 0(比如已 start 过、已终止、或正在运行),立即抛出
IllegalThreadStateException; - 只有通过校验,才继续执行后续逻辑,确保状态转换只发生一次。
start() 内部三步关键动作
成功通过状态检查后,start() 会依次完成以下操作,每一步都对应状态机中不可逆的推进:
立即学习“Java免费学习笔记(深入)”;
- 将当前线程对象加入所属
ThreadGroup,完成 JVM 层注册; - 调用本地方法
start0()—— 这是真正触发操作系统创建内核线程(如 Linux 的clone())、分配栈空间、初始化 PCB 的环节; - 一旦
start0()返回,JVM 就把该线程标记为 RUNNABLE(就绪态),意味着它已准备好被调度器选中执行。
RUNNABLE 不等于正在运行
进入 RUNNABLE 状态,仅表示线程具备了运行资格,并非立刻占用 CPU:
- 它可能在等待 CPU 时间片(操作系统调度队列中排队);
- 也可能因 I/O、锁竞争等暂时让出 CPU,但只要没进入 BLOCKED/WAITING/TIMED_WAITING,仍属于 RUNNABLE;
- 这是 Java 线程模型与 OS 调度解耦的设计体现:JVM 不控制何时真正执行,只负责“上线”和“状态声明”。
为什么不能重复 start?
因为线程状态机不允许从 RUNNABLE 或其他任何非-NEW 状态回退或再次跃迁到 RUNNABLE:
- 源码中
threadStatus在start0()成功后就被设为非零值(如 2 表示 RUNNABLE); - 再次调用
start()时,校验失败,直接拒绝,避免出现“一个 Thread 对象对应多个系统线程”的语义错误; - 这保证了 Java 线程对象与底层 OS 线程之间的一对一映射关系。


















