Thread类中run和start的区别

我们先看一个简单例子

java 复制代码
public class SimpleExample {
    public static void main(String[] args) {
        System.out.println("=== 故事开始 ===");
        
        // 创建一个"唱歌"任务
        Thread singThread = new Thread(() -> {
            System.out.println("[唱歌线程] 开始唱歌...");
            try {
                Thread.sleep(3000); // 唱3秒钟
            } catch (Exception e) {}
            System.out.println("[唱歌线程] 唱完歌了");
        });
        
        System.out.println("\n--- 第1次测试:用run() ---");
        System.out.println("[主线程] 调用singThread.run()");
        singThread.run();  // 调用run()
        System.out.println("[主线程] run()调用完毕");
        
        System.out.println("\n--- 第2次测试:用start() ---");
        // 重新创建线程(因为一个Thread对象只能start一次)
        singThread = new Thread(() -> {
            System.out.println("[唱歌线程] 开始唱歌...");
            try {
                Thread.sleep(3000);
            } catch (Exception e) {}
            System.out.println("[唱歌线程] 唱完歌了");
        });
        
        System.out.println("[主线程] 调用singThread.start()");
        singThread.start();  // 调用start()
        System.out.println("[主线程] start()调用完毕");
        
        // 主线程等一会儿,看看效果
        try {
            Thread.sleep(5000);
        } catch (Exception e) {}
        System.out.println("\n=== 故事结束 ===");
    }
}

运行结果对比

=== 故事开始 ===

--- 第1次测试:用run() ---

主线程\] 调用singThread.run() \[唱歌线程\] 开始唱歌... (这里会卡住3秒钟,因为Thread.sleep(3000)) \[唱歌线程\] 唱完歌了 \[主线程\] run()调用完毕 --- 第2次测试:用start() --- \[主线程\] 调用singThread.start() \[主线程\] start()调用完毕 ← 注意!这里立即输出,没有等待! \[唱歌线程\] 开始唱歌... (这里主线程继续运行,唱歌在后台进行) === 故事结束 === \[唱歌线程\] 唱完歌了 ← 可能在这里输出,因为唱得慢

最关键的区别

  1. 卡不卡的区别
  • 用run() :程序会卡住3秒 ,因为Thread.sleep(3000)在当前线程执行

  • 用start() :程序不卡,主线程继续运行,唱歌在后台慢慢唱

  1. 顺序的区别
  • 用run():一定是这个顺序:

    1. "[唱歌线程] 开始唱歌..."

    2. (等待3秒)

    3. "[唱歌线程] 唱完歌了"

    4. "[主线程] run()调用完毕"

  • 用start():顺序不确定,可能是:

    1. "[主线程] start()调用完毕" ← 先输出!

    2. "[唱歌线程] 开始唱歌..." ← 后输出

      或者反过来,因为两个线程同时运行

再看一个简单的例子

public class MostSimple {

public static void main(String[] args) throws Exception {

Thread t = new Thread(() -> {

System.out.println("我是新线程,我的名字是:" + Thread.currentThread().getName());

});

System.out.println("主线程名字:" + Thread.currentThread().getName());

System.out.println("\n--- 用run() ---");

t.run(); // 注意看输出的线程名!

System.out.println("\n--- 用start() ---");

t.start();

Thread.sleep(100); // 等新线程执行完

}

}

运行结果:

主线程名字:main

--- 用run() ---

我是新线程,我的名字是:main ← 注意!还是main线程!

--- 用start() ---

我是新线程,我的名字是:Thread-0 ← 看!线程名变了!

run() = 你自己干活(当前线程执行代码)
start() = 叫别人干活(创建新线程执行代码)

总结:

  1. 用run() :代码在当前线程执行,会卡住当前线程

  2. 用start() :代码在新线程执行,不卡当前线程

  3. 用run() :输出的线程名不变

  4. 用start() :输出的线程名会变

相关推荐
n 55!w !1082 小时前
js练习作业
开发语言·javascript·ecmascript
计算机程序设计小李同学2 小时前
基于位置服务的二手图书回收平台
java·前端·vue.js·spring boot·后端
Whisper_Sy2 小时前
Flutter for OpenHarmony移动数据使用监管助手App实战 - 月报告实现
android·开发语言·javascript·网络·flutter·ecmascript
灰灰勇闯IT2 小时前
【Flutter for OpenHarmonyDart 入门日记】第5篇:字典类型 Map 与动态类型 dynamic 全解析
开发语言·javascript·ecmascript
leaves falling2 小时前
c语言- 有序序列合并
c语言·开发语言·数据结构
雨季6662 小时前
Flutter for OpenHarmony 入门实践:从 Scaffold 到 Container 的三段式布局构建
开发语言·javascript·flutter
青云交2 小时前
Java 大视界 -- 基于 Java+Flink 构建实时风控规则引擎:动态规则配置与热更新(446)
java·nacos·flink·规则引擎·aviator·实时风控·动态规则
Dreamy smile2 小时前
JavaScript 继承与 this 指向操作详解
开发语言·javascript·原型模式
副露のmagic2 小时前
更弱智的算法学习 day53
开发语言·python