Java New Thread start() 与 run()的区别

理解Java线程执行方式:run() vs start()区别
本文深入探讨了Java线程执行中的两种方式:使用run()直接执行Runnable任务与使用start()启动新线程执行任务的区别。重点解释了两者在实际应用中的优劣及如何避免主线程阻塞导致的ANR问题。

考虑下面两个代码片段:

代码1:
{
    @Override
    public void run()
    {
        //background task?
    }

}).run();
代码2:
{
    @Override
    public void run()
    {
        //background task?
    }

}).start();

代码1中使用了run()来执行runnable里面的代码。根据Thread的文档,这里实际上没有另开线程执行操作,runnable里面的代码会运行在当前线程,所以如果代码1是在主线程调用而且runnable里面有耗时操作的话就会阻塞主线程造成ANR。

代码2与代码1的区别是使用start()来执行runnable里面的代码,从Thread的文档可知start()会启动一个新的线程来执行代码。因此,如果有耗时代码的话记得用Thread.start()来操作。

———— start

public synchronized void start ()

Added in API level 1
Starts the new Thread of execution. The run() method of the receiver will be called by the receiver Thread itself (and not the Thread calling start()).

———— run

public void run ()

Added in API level 1
Calls the run() method of the Runnable object the receiver holds. If no Runnable is set, does nothing.

可以看出,run()仅仅是把thread的runnable对象的run()调用了一次。

### Java 中 `Thread` 类的 `run()` 方法 `start()` 方法的区别及使用场景 #### 1. 基本概念 在 Java 的多线程编程中,`Thread` 类提供了两个核心方法:`run()` 和 `start()`。这两个方法的功能和用途有显著差异。 - **`start()` 方法** 当调用 `start()` 方法时,它会触发 JVM 创建一个新的线程并执行该线程的任务[^1]。新线程一旦被创建,JVM 就会在后台自动调用 `run()` 方法来运行线程的具体逻辑。因此,`start()` 是真正用于启动线程的方法。 - **`run()` 方法** 这是一个普通的实例方法,通常由开发者重写以定义线程要执行的具体任务。如果直接调用 `run()` 方法而不是通过 `start()` 启动线程,则其行为类似于普通方法调用,在当前线程上下文中执行,而不会开启新的线程[^3]。 #### 2. 工作机制对比 当调用 `start()` 方法时,JVM 执行以下操作: - 初始化新线程的相关资源。 - 切换到就绪状态等待 CPU 调度。 - 在获得调度权后,进入运行状态并通过内部机制调用 `run()` 方法完成实际工作[^4]。 然而,直接调用 `run()` 不涉及上述过程;它只是简单地作为常规函数被执行,无法实现真正的并发处理[^2]。 #### 3. 使用场景分析 以下是两种方法适用的不同情况: - **使用 `start()`** - 需要在独立的新线程里执行某些耗时或阻塞的操作。 - 实现程序内的并发控制,提高效率或者分离业务逻辑。 - **直接调用 `run()`** - 测试阶段快速验证 `run()` 内部代码逻辑是否正常运作而不必考虑多线程环境的影响。 - 特定情况下不需要利用额外线程仅需顺序执行某段流程时可采用这种方式简化开发复杂度。 #### 示例代码展示 下面给出一段基于前述理论的实际应用例子说明如何正确运用这两种方式: ```java public class MyTask extends Thread { @Override public void run() { System.out.println(Thread.currentThread().getName()+" says Hello!"); } public static void main(String[] args) throws InterruptedException{ MyTask task=new MyTask(); // 正确做法: 开启子线程 task.start(); /* 输出可能是(取决于CPU调度): Thread-0 says Hello! main continues... */ // 错误示范: 只是在主线程内模拟了单一线程的行为 task.run(); /* 输出总是: main says Hello! */ System.out.println("main continues..."); } } ``` #### 总结 综上所述,理解并区分 `start()` 和 `run()` 对于掌握 Java线程至关重要。只有合理选用它们才能充分发挥多核处理器的优势从而构建高效稳定的软件系统。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值