调用 run() 方法不会启动新线程,它仅在当前线程中同步执行,无并发效果;start() 才真正创建并启动新线程,实现调度层面的并发。
直接调用 run() 方法不会启动新线程,它只是在当前线程里像普通函数一样顺序执行,完全不产生并发效果。
run() 本质就是一个普通方法
run() 方法本身没有创建线程的能力,它只是被设计为“线程该做什么”的逻辑容器。无论是 Java 还是 Python 的 Thread 类,run() 都是一个可重写的实例方法,和 toString() 或 getName() 没有本质区别——调用它不会触发任何底层线程资源分配。
- Java 中:
thread.run()就是主线程里的一次同步方法调用,执行完才继续下一行 - Python 中:同样不新建线程,所有代码仍在主线程中阻塞运行
- 即使你重写了
run(),加了循环、sleep、IO 等操作,也改变不了它“单线程串行执行”的事实
start() 才是真正开启线程的开关
start() 是由 JVM(Java)或 CPython 解释器(Python)深度集成的特殊方法,它会触发操作系统级的线程创建流程:
- 申请内核线程资源(如 pthread_create)
- 设置独立的栈空间和执行上下文
- 将
run()注册为该线程的入口函数 - 把新线程加入调度队列,等待 CPU 时间片
只有这时,run() 才会在一个**与主线程隔离的新执行路径中运行**,实现真正的并发(至少在调度层面)。
常见误解与后果
新手容易以为“只要进了 run 就算多线程”,但实际行为可能让人困惑:
- 写两个
thread.run()调用?→ 仍是主线程里一前一后执行,总耗时≈两者相加 - 写
thread.run()再跟thread.start()?→ 前者立即执行,后者稍后异步执行,逻辑错乱 - 调试时断点停在
run()里,发现线程名还是 “MainThread”?→ 因为确实没换线程
Python 特别提醒:GIL 不影响这个原理
虽然 CPython 的 GIL 会让多个线程无法真正并行执行 CPU 密集任务,但这和“是否启动了新线程”是两回事:
- 调用
start()→ 确实创建了新线程(threading.enumerate()可见),只是受 GIL 限制不能同时跑字节码 - 调用
run()→ 根本没新线程,连“被 GIL 限制”的资格都没有 - I/O 操作(如文件读写、网络请求)在线程中仍能释放 GIL,此时
start()启动的线程才能体现并发优势

















