调用start()方法后线程进入RUNNABLE状态,JVM验证状态、分配资源、创建原生线程并注册调度队列;直接调用run()仅是普通方法执行,不启动新线程,无法实现并发。

调用 start() 方法后,线程从新建(NEW)状态正式进入就绪(RUNNABLE)状态——这不是靠 Java 代码“手动切换”的,而是 JVM 内部机制协同操作系统完成的。
start() 执行时发生了什么
当你调用 thread.start(),JVM 会做几件关键的事:
- 验证线程状态:如果该线程已启动过(即不是 NEW 状态),直接抛出
IllegalThreadStateException; - 为线程分配底层资源:包括栈空间、程序计数器、本地方法栈等;
- 向操作系统发起系统调用(如
pthread_create在 Linux 上),请求创建一个原生线程; - 将线程注册进 JVM 的线程调度队列,并将其状态设为 RUNNABLE(Java 中的“就绪”状态);
- 返回,不等待线程真正执行——start() 是异步的,立即返回。
就绪状态的本质
RUNNABLE 状态在 Java 中其实包含两层含义:
- 线程已准备好运行(runnable),但还没被 CPU 选中;
- 也可能正在 CPU 上运行(running)——Java 不区分“就绪”和“运行”,统一用 RUNNABLE 表示“可运行或正在运行”;
- 真正阻塞(比如 I/O 等待、锁竞争、sleep)时,才会离开 RUNNABLE 进入 BLOCKED、WAITING 或 TIMED_WAITING 等状态。
为什么不能直接调用 run()
直接调用 thread.run() 只是普通方法调用:
立即学习“Java免费学习笔记(深入)”;
- 不会触发 JVM 创建新线程,所有代码仍在当前线程(比如主线程)中同步执行;
- 线程对象状态仍停留在 NEW,不会变成 RUNNABLE;
- 没有独立调用栈,无法实现真正的并发。
常见误区提醒
几个容易混淆的关键点:
- start() 不等于立刻执行:它只是“报名排队”,何时执行取决于 CPU 调度,可能毫秒级延迟,也可能更久;
- 就绪 ≠ 正在跑:RUNNABLE 状态下线程没拿到时间片,就不会执行 run() 里的代码;
- 状态不可逆:一旦 start() 成功,线程只能向前走(RUNNABLE → RUNNING → TERMINATED 等),不能再回到 NEW 或重复 start。


















