必须用start()启动线程,它触发JVM创建OS线程、分配资源并使状态变为RUNNABLE,之后自动回调run()实现并发;而run()只是普通方法调用,不创建新线程,始终在当前线程串行执行,导致“假并发”。

启动线程必须用 start() 方法,不能用 run() 方法。
start() 才是真正启动线程的合法方式
调用 start() 会触发 JVM 向操作系统申请资源,创建一个独立的 OS 线程,分配栈空间和线程 ID,并把线程状态从 NEW 改为 RUNNABLE。之后由 JVM 在合适时机自动回调 run() 方法——你不用手动调,也不控制执行时间。此时主线程继续运行,子线程在后台并发执行。
- 只能调用一次,重复调用抛 IllegalThreadStateException
- 线程能被 interrupt() 中断、被线程池管理、响应优先级调度
- 子线程中
Thread.currentThread().getName()返回的是该线程名(如 "t1")
run() 只是一个普通 Java 方法
直接调用 run() 不创建新线程,不改变线程状态,所有代码仍在当前线程(比如 main)里同步执行。它没有并发能力,和调用 obj.doSomething() 没本质区别。
在调试 Java 后端 API 故障时使用此技能,尤其适用于以下任务:分析日志、跨 Controller、Service 和 Mapper 层追踪请求、定位异常根因、检查 SQL 执行或参数流转,以及生成简洁的诊断结论与修复方案。
- 可反复调用,无限制,但始终串行运行
- 若 run() 里有
Thread.sleep(5000),当前线程就会卡住 5 秒 -
t1.run(); t2.run();是严格顺序执行,不是并发 - 其中
Thread.currentThread().getName()永远显示 "main"
常见误用后果很隐蔽
表面看程序能跑、输出也对,但实际是“假并发”:所有逻辑挤在主线程里串行执行,完全失去多线程意义。线上因此导致性能瓶颈、响应延迟、吞吐量上不去的情况很常见。
立即学习“Java免费学习笔记(深入)”;
- 用 run() 替代 start(),线程永远停在 NEW 状态,生命周期没开始
- 想用多线程提速,结果反而因阻塞主线程变得更慢
- 后续加 interrupt()、join()、线程池等机制全部失效

















