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() :输出的线程名会变

相关推荐
砍材农夫2 分钟前
spring-ai 第六模型介绍-聊天模型
java·人工智能·spring
勿忘,瞬间5 分钟前
数据结构—顺序表
java·开发语言
张張4089 分钟前
(域格)环境搭建和编译
c语言·开发语言·python·ai
weixin_4235339913 分钟前
【Windows11离线安装anaconda、python、vscode】
开发语言·vscode·python
fzb5QsS1p16 分钟前
告别重复造轮子,Qt 快速开发脚手架
开发语言·qt·php
航Hang*18 分钟前
第3章:Linux系统安全管理——第2节:部署代理服务
linux·运维·服务器·开发语言·笔记·系统安全
周杰伦fans19 分钟前
C# required 关键字详解
开发语言·网络·c#
一蓑烟雨,一任平生20 分钟前
鸿蒙H5调试方法
前端·华为·h5·harmonyos
༾冬瓜大侠༿21 分钟前
vector
c语言·开发语言·数据结构·c++·算法
Canace33 分钟前
使用大模型来维护知识库
前端·人工智能