线程从NEW切换到RUNNABLE必须调用start()方法;该方法触发JVM向操作系统申请内核线程、分配栈与PC寄存器、并将线程加入调度队列,而run()仅是普通方法调用,不产生新线程。

线程从 NEW 切换到 RUNNABLE,不是靠构造、不是靠赋值、更不是靠运气——它必须调用 start() 方法。这个调用是 JVM 向操作系统发起的一次正式“注册申请”,缺它不可。
NEW 状态只是个“空壳”
当你写下 Thread t = new Thread(() -> {...});,JVM 只是在堆里创建了一个 Thread 对象,此时:
- 没有操作系统线程资源
- 没有独立的虚拟机栈和程序计数器
- 不在任何调度队列中
- 甚至不能被 CPU 看见
它就像一张没盖章的工牌,名义上是员工,但没录入系统、没分配工位、没排班表。
start() 是唯一合法的“激活开关”
start() 不是普通 Java 方法,它是 JVM 的入口级协作机制,内部完成三件关键物理动作:
- 向操作系统申请内核线程(真正意义上的“线程实体”)
- 为该线程分配专属的 Java 虚拟机栈和程序计数器
- 将线程状态设为 RUNNABLE,并加入 JVM 线程调度器的可运行队列
这整个过程不可跳过、不可模拟、不可绕行——哪怕你反射修改状态字段,也无法获得真实执行能力。
别拿 run() 当启动,它只是个普通方法
直接调用 t.run():
- 不触发任何线程资源分配
- 不改变线程状态(t 仍处于 NEW 或其它原状态)
- 所有代码仍在当前线程(比如 main)中同步执行
- 完全没有并发性,也不产生新线程上下文
它等价于你把一段逻辑封装成 void 方法,然后手动调用了一次——和多线程毫无关系。
重复调用 start() 会立即失败
start() 设计为一次性操作:
- 第二次调用抛出 IllegalThreadStateException
- JVM 会检查线程是否已启动或已终止
- 这种强约束恰恰说明:状态切换不是状态机随便翻页,而是伴随真实资源生命周期的刚性绑定

















