start()方法是java线程启动的唯一入口,它不直接调度cpu,而是触发jvm向操作系统发起线程创建请求,完成资源分配、状态变更(new→runnable)及os线程注册,由os调度器决定何时执行run()方法。

Java 中的 start() 方法本身并不直接把任务“交给 CPU”,而是触发 JVM 向操作系统发起线程创建请求,由操作系统内核完成线程调度准备;真正执行任务代码的是该线程启动后,JVM 调用其 run() 方法时,CPU 才开始执行对应字节码指令。
start() 做了什么(而非直接调度)
start() 是 Thread 类的本地方法(native),它的核心作用是:
- 为线程分配 JVM 内部资源(如程序计数器、虚拟机栈、本地方法栈)
- 将线程状态从
NEW改为RUNNABLE - 向底层操作系统(如 Linux 的
pthread_create)发起系统调用,创建一个与之关联的 OS 线程 - 注册该 OS 线程到操作系统的调度队列中,等待被 CPU 选中执行
CPU 调度发生在 OS 层,JVM 不参与具体时间片分配
JVM 不控制 CPU 怎么切时间片、哪个线程优先运行——这是操作系统内核(如 Linux CFS 调度器)的职责。JVM 只负责:
- 把 Java 线程映射为一个 OS 线程(1:1 模型,HotSpot 默认)
- 在 OS 线程启动后,自动调用该线程绑定的
run()方法 - 当线程进入阻塞(如 I/O、
wait()、锁竞争)或终止时,通知 OS 将其从运行队列移出
也就是说,start() 是“启动请求”的起点,而 CPU 是否立即执行、执行多久、何时再调度,完全由 OS 决定。
为什么不能直接调用 run()?
直接调用 run() 只是普通方法调用,仍在当前线程(比如 main 线程)中同步执行,不会创建新 OS 线程,也不会进入 OS 调度队列:
- 线程状态保持
NEW或TERMINATED,不会变成RUNNABLE - 没有独立栈空间,无法实现真正的并发
- CPU 不会把它当作一个可调度实体,自然谈不上“交由 CPU 调度”
简单看一个实际流转过程
以如下代码为例:
new Thread(() -> { System.out.println("Hello"); }).start();执行流程大致为:
- JVM 创建
Thread对象,状态为NEW - 调用
start()→ JVM 调用 native 方法 → OS 创建线程并加入就绪队列 - OS 调度器在某个时刻选中该线程 → CPU 切换上下文,开始执行其指令
- JVM 在该 OS 线程上下文中调用
run()→ 执行 lambda 中的System.out.println
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











