一句话总结:
start() 是“点火发射线程”,run() 是“线程要干的活”。直接调用 run() 等于“自己干”,而调用 start() 是“雇个人帮你干”!
一、核心区别
| 方法 | 作用 | 线程行为 |
|---|---|---|
start() | 启动一个新线程,让JVM调用 run() 方法,真正实现多线程。 | 新线程并行执行任务。 |
run() | 定义线程要执行的任务代码。直接调用 run() 不会启动新线程。 | 在当前线程(如主线程)同步执行。 |
二、举个现实例子
-
场景:你要搬砖(任务),有两种选择:
-
直接调用
run():- 自己动手搬砖(代码在当前线程执行)。
- 结果:累死累活,效率低(没有多线程)。
-
调用
start():- 雇个工人(新线程)帮你搬砖(执行
run())。 - 结果:你可以继续喝茶,工人并行搬砖(多线程并发)。
- 雇个工人(新线程)帮你搬砖(执行
-
三、代码示例
public class ThreadDemo {
public static void main(String[] args) {
// 创建一个线程对象
Thread thread = new Thread(() -> {
System.out.println("线程任务执行中,当前线程:" + Thread.currentThread().getName());
});
// 错误用法:直接调用 run()
thread.run();
// 输出:线程任务执行中,当前线程:main(在主线程执行,没有新线程!)
// 正确用法:调用 start()
thread.start();
// 输出:线程任务执行中,当前线程:Thread-0(新线程执行)
}
}
四、关键点
-
start()的底层原理:- 调用
start()后,JVM会创建一个新线程,并触发线程的run()方法。 - 只能调用一次:多次调用
start()会抛出IllegalThreadStateException。
- 调用
-
直接调用
run()的问题:- 代码会在当前线程(如主线程)同步执行,不会启动新线程。
- 完全失去了多线程的意义!
-
线程生命周期:
start()让线程从 NEW状态 → RUNNABLE状态。run()只是普通方法,和线程状态无关。
五、常见错误
-
误以为调用
run()能启动线程:Thread thread = new Thread(() -> System.out.println("Hello")); thread.run(); // 输出 Hello,但这是主线程干的! -
重复调用
start():thread.start(); thread.start(); // 抛出 IllegalThreadStateException
六、总结
- 用
start()启动线程:实现多线程并行。 run()只是任务定义:别指望它开新线程。- 设计原则:Java将“任务定义”(
run())和“线程启动”(start())分离,提高灵活性。
口诀:
「start点火新线程,run是任务别搞错
直接调用run方法,主线程里同步做
多线程要并行跑,start才是正确路!」