调用 start()
方法和直接调用 run()
方法在 Java 中有本质上的区别。理解这两者的区别对于正确使用多线程编程至关重要。
调用 start()
方法
当调用 start()
方法时,Java 虚拟机(JVM)会为你创建一个新的线程并执行该线程的 run()
方法。这意味着 run()
方法中的代码将会在一个新的线程中并行运行。
示例:
class MyThread extends Thread {
@Override
public void run() {
System.out.println("Thread is running");
}
}
public class Main {
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start(); // 启动新线程,run() 方法将在新线程中运行
}
}
直接调用 run()
方法
当直接调用 run()
方法时,run()
方法中的代码将会在调用它的当前线程中执行,而不会启动一个新的线程。这只是一个普通的方法调用,不涉及任何多线程操作。
示例:
class MyThread extends Thread {
@Override
public void run() {
System.out.println("Thread is running");
}
}
public class Main {
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.run(); // 直接调用 run() 方法,run() 方法将在主线程中运行
}
}
为什么要调用 start()
方法而不是直接调用 run()
方法
-
启动新线程:
start()
方法会启动一个新线程并调用run()
方法。通过这种方式,run()
方法中的代码可以在新线程中并行执行,从而实现多线程并发。 -
线程管理:调用
start()
方法后,线程会被正确地初始化和管理,包括分配资源、设置优先级、调度执行等。这些都是 JVM 负责的复杂任务,而直接调用run()
方法不会触发这些操作。 -
线程生命周期:通过调用
start()
方法,可以正确地管理线程的生命周期,包括线程的创建、运行和终止。这对于编写可靠的多线程程序至关重要。
示例对比
以下示例展示了调用 start()
和直接调用 run()
方法的区别:
class MyThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + " - " + i);
}
}
}
public class Main {
public static void main(String[] args) {
MyThread thread1 = new MyThread();
MyThread thread2 = new MyThread();
// 调用 start() 方法
thread1.start();
thread2.start();
// 直接调用 run() 方法
// thread1.run();
// thread2.run();
}
}
当调用 start()
方法时,输出结果将类似于:
Thread-0 - 0
Thread-1 - 0
Thread-0 - 1
Thread-1 - 1
Thread-0 - 2
Thread-1 - 2
...
因为两个线程是并行运行的。
当直接调用 run()
方法时,输出结果将类似于:
main - 0
main - 1
main - 2
main - 3
main - 4
main - 0
main - 1
main - 2
main - 3
main - 4
因为 run()
方法在主线程中顺序执行。
结论
调用 start()
方法可以创建和启动新线程,从而实现并行执行。直接调用 run()
方法只是在当前线程中执行代码,不会启动新线程。因此,在编写多线程程序时,应使用 start()
方法来确保线程的正确启动和管理。