Java 中 start() 和 run() 方法的区别

2025年7月7日 | 阅读 5 分钟

多线程是 Java 的核心功能,它允许程序中的两个或多个部分并发执行,从而最大化 CPU 利用率。Java 提供了 Thread 类和 Runnable 接口来实现多线程。

start() 方法定义在 Thread 类中,而 run() 方法定义在 Runnable 接口中,并由 Thread 类实现。虽然它们乍一看可能很相似,但它们的作用不同。

Thread.start() 方法

Thread.start() 方法用于启动新线程的执行。当我们调用 start() 方法时,JVM 会创建一个新的系统级线程。然后,系统级线程会在新创建的线程上内部调用 run() 方法。它实现了并发执行。

总的来说,我们可以说 start() 方法并发运行两个线程。当前线程(从 start() 方法调用返回的线程)和另一个线程(执行其 run() 方法的线程)。

语法

start() 方法负责:

  1. 为新线程分配系统资源。
  2. 在单独的执行线程中调用 Thread 对象的 run() 方法。
  3. 管理线程的生命周期(启动、运行和终止线程)。
  4. 请注意,对同一个 Thread 对象多次调用 start() 方法将导致 **IllegalThreadStateException**。每个线程只能启动一次。

示例:创建和启动线程

示例

编译并运行

输出

Running thread through the start() method.

解释

在上面的程序中,start() 方法实际上启动了新线程。它在内部通过新的调用栈调用 run() 方法,从而实现了真正的多线程。

如果我们使用 t1.run() 而不是 t1.start(),它将在主线程上运行,而不是创建新线程。通过调用 start() 方法,Java 会创建一个新线程并将任务委托给您重写的 run() 方法。

Thread.run() 方法

run() 方法包含要在线程中执行的代码。但是,如果直接调用它(即不使用 start() 方法),它就像一个普通方法一样工作,并且不会创建新线程。它在当前线程(通常是主线程)的上下文中执行,而没有多线程的好处。

语法

示例:创建和运行线程

示例

编译并运行

输出

Thread 1: Count 1
Thread 12: Count 1
Thread 1: Count 2
Thread 12: Count 2
Thread 12: Count 3
Thread 12: Count 4
Thread 12: Count 5
Thread 1: Count 3
Thread 1: Count 4
Thread 1: Count 5

注意:您的输出可能会有所不同,因为程序每次运行时都会生成唯一的输出。

解释

上面的程序只是从 1 计数到 5,并打印当前线程 ID 和计数。

在 main() 方法中,我们创建了 Main 类的两个实例 thread1 和 thread2。我们使用 start() 方法启动 thread1,并使用 run() 方法执行 thread2。thread1 是使用 start() 方法创建的,并在单独的线程中运行,其 run() 方法与主线程(由线程 ID 12 标识)并发执行。从交错的输出中可以看出并发执行。

thread2 是使用 run() 创建的,它只是在主线程的上下文中执行 run() 方法。因此,没有并发执行,thread2 的输出出现在 thread1 执行完毕之后。

输出说明了 Java 线程中 start() 和 run() 方法之间的关键区别:start() 创建一个新线程以进行并发执行,而 run() 在当前线程中顺序执行代码。

start() 和 run() 方法之间的区别

特性start() 方法run() 方法
线程创建它创建一个新线程。它不创建新线程。
执行线程它在新线程中执行 run() 方法。它在并发线程中执行 run() 方法。
并发性它实现了真正多线程。它不实现多线程,意味着它就像一个普通的方法调用。
定义于它定义在 java.lang.Thread 类中。它定义在 java.lang.Runnable 接口中。
多次调用如果方法被调用两次,它将抛出 IllegalThreadStateException。像任何方法一样,它可以被调用多次。

结论

在 Java 中,在处理多线程时,理解 start() 和 run() 方法之间的区别至关重要。start() 方法用于启动新线程,并负责管理线程的生命周期。

另一方面,run() 方法定义了线程执行的实际代码。通过恰当地使用这些方法,我们可以连接多线程的力量来创建高效且响应迅速的 Java 应用程序。

Java start() 和 run() 方法选择题

1. 关于 start() 方法,以下哪个陈述是正确的?

  1. 它直接在当前线程中执行 run() 方法
  2. 它创建一个新线程并内部调用 run() 方法
  3. 它用于定义线程的逻辑
  4. 它不是 Thread 类的一部分
 

答案:B)

解释: start() 方法创建一个新线程并在该新线程上内部调用 run() 方法。


2. 如果直接调用 run() 方法而不是 start() 会发生什么?

  1. 创建一个新线程并执行
  2. run() 方法将不会被调用
  3. run() 方法在当前线程中执行
  4. 它会抛出异常
 

答案:C)

解释: 直接调用 run() 就像一个普通的方法调用,它在当前线程中执行,而不是在新线程中执行。


3. 必须重写哪个方法来定义线程将执行的代码?

  1. start()
  2. stop()
  3. wait()
  4. run()
 

答案:D)

解释: 必须重写 run() 方法来定义线程启动时将执行的操作。


4. 如果在线程类中直接调用 run() 方法而不是 start(),输出会是什么?

  1. 运行时异常
  2. 程序以多线程方式运行
  3. 程序正常运行,不创建新线程
  4. 编译错误
 

答案:C)

解释: 直接调用 run() 只是像调用普通方法一样调用它,不会创建新线程。


5. 以下哪个最好地区分了 start() 和 run()?

  1. start() 不是 Thread 类的一部分
  2. run() 启动新线程,start() 不启动
  3. start() 启动新线程,run() 不启动
  4. start() 由 JVM 调用,run() 不能被重写
 

答案:C)

解释: start() 创建一个新线程并在其中执行 run(),而单独的 run() 像普通方法一样执行,而不创建新线程。