调用Thread.start()后线程状态从NEW变为RUNNABLE,是JVM底层配合操作系统完成的原子性跃迁:先校验状态,再分配栈资源、绑定OS线程、注册调度系统,最终原子更新状态;RUNNABLE表示已就绪可调度,并非正在运行。

Java 中调用 Thread.start() 方法后,线程状态从 NEW 变为 RUNNABLE,不是因为 Java 代码直接修改了状态字段,而是由 JVM 底层配合操作系统完成的原子性状态跃迁。
start() 方法做了什么
start() 是启动线程的唯一合法方式。它内部会校验线程状态:只有当前状态为 NEW 时才允许执行;否则抛出 IllegalThreadStateException。校验通过后,JVM 执行以下关键动作:
- 为该线程分配并初始化本地线程栈(Native Stack)和程序计数器等资源
- 将 Java 线程对象与底层 OS 线程(如 pthread 或 Windows thread)绑定
- 把线程注册进 JVM 的线程调度系统,并标记其进入就绪队列(Ready Queue)
- 触发 JVM 将线程状态原子地更新为 RUNNABLE(此过程不可被 Java 层干预或中断)
RUNNABLE 状态的真实含义
注意:RUNNABLE 不等于“正在运行”,而是表示“已准备好、可被 CPU 调度执行”。此时线程可能处于:
- 等待 CPU 时间片(在操作系统就绪队列中排队)
- 正在某个 CPU 核心上执行
run()方法中的代码 - 因 I/O 未就绪而短暂让出 CPU(但未阻塞,仍属 RUNNABLE)
也就是说,一旦 start() 成功返回,线程状态立刻变为 RUNNABLE —— 这个转变发生在 native 层,不依赖 run() 方法是否已真正开始执行。
立即学习“Java免费学习笔记(深入)”;
为什么不能直接调用 run()?
直接调用 thread.run() 只是普通方法调用,不会触发任何线程状态变更:
- 线程仍保持 NEW(如果还没 start)或其它旧状态
- 所有代码仍在当前线程(比如 main 线程)中同步执行
- JVM 不为其创建 OS 线程,也不更新其状态字段
所以 run() 只是任务逻辑的载体,start() 才是开启并发生命周期的开关。
状态变化可被观测但不可干预
你可以用 thread.getState() 观察状态跃迁,例如:
t.start();
System.out.println(t.getState()); // 极大概率输出 RUNNABLE
但这个状态更新完全由 JVM 在 native 层控制,Java 层无法手动设置或拦截。即使在 start() 返回前插入断点,你也看不到中间态 —— JVM 保证状态变更的原子性和可见性。


















