妹子问我为啥启动线程时使用 start 而不是 run

简介: 今天团队里面的妹子问阿粉,为什么在启动线程的时候,都使用 start 方法,而不是 run 方法呢还好阿粉平时一直有在学习,要不真的被妹子问住了在多线程中,如果想让一个线程启动,你使用的方法一定是 thread.start() 方法,而不是 thread.run() 方法(啥,你用的不是 thread.start() 方法?乖,你的打开方式不对哦,下次不要这样了有没有疑惑,为什么每次我们都习惯调用 start() 方法,为什么不直接调用 run() 方法来启动线程呢?而且如果去看源码的话,你会发现,在 thread.start() 方法中,其实最后还是调用了 thread.ru

今天团队里面的妹子问阿粉,为什么在启动线程的时候,都使用 start 方法,而不是 run 方法呢

还好阿粉平时一直有在学习,要不真的被妹子问住了

在多线程中,如果想让一个线程启动,你使用的方法一定是 thread.start() 方法,而不是 thread.run() 方法(啥,你用的不是 thread.start() 方法?乖,你的打开方式不对哦,下次不要这样了

有没有疑惑,为什么每次我们都习惯调用 start() 方法,为什么不直接调用 run() 方法来启动线程呢?

而且如果去看源码的话,你会发现,在 thread.start() 方法中,其实最后还是调用了 thread.run() 方法来执行

Causes this thread to begin execution; the Java Virtual Machine
 calls the <code>run</code> method of this thread.

上面的注释翻译一下:当线程开始执行时, JVM 会调用此线程的 run 方法

也就是说,线程的 run 方法是由 JVM 直接调用的,在 Java 中如果我们想要直接调用 run 方法也是可以的,因为在 Java 中 run 方法是 public 的

@Override
    public void run() {
        if (target != null) {
            target.run();
        }
    }

那既然 start 方法最后调用的也是 run 方法,再加上 run 方法本身支持直接调用,那为啥我们平时写的程序都是调用 start 方法,而不是 run 方法呢

那是因为,如果直接调用 run 方法,就不是多线程了

为了方便解释,咱们看个小 demo :

public class RunThread {
    public static void main(String[] args) {
        Thread runThread = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.printf("Run begin another , 当前线程 : %s.%n" ,Thread.currentThread().getName());
            }
        });
        // 启动线程
        runThread.start();
        // 直接调用 run 方法 -- 演示使用,实际中不要这么做!
        runThread.run();
        System.out.printf("Run begin , 当前线程 : %s.%n" ,Thread.currentThread().getName());
    }
}

上面的程序运行结果如下:

61.jpg

你会发现, runThreadrun 方法被执行了两次

一次是 run 方法运行在自己的线程中,从 Run begin another , 当前线程 : Thread-0 可以看到,这个线程是运行在 Thread-0

另外一次是因为我们的程序代码直接调用了 run 方法,此时的线程运行在 main 线程中,从 Run begin another , 当前线程 : main 可以看出来

也就是说,如果我们直接调用 run 方法的话,线程并不是运行在自己的线程中,而是运行在了当前线程中

我们为什么要创建多线程?不就是希望多个线程并行执行,比如现在我是线程 A ,此时又起了一个线程,那么我希望这个线程是和线程 A 一起运行的,如果直接调用了 run 方法的话,就运行在线程 A 里面来了

并没有达到创建多线程的目标,这怎么行呢,对不对

所以在启动线程时,都是使用 start 方法,而不是 run 方法

这一点,其实在源码中也有说明:

the Java Virtual Machine calls the run method of this thread.
The result is that two threads are running concurrently: 
 the current thread (which returns from the call to the start method) 
 and the other thread (which executes its run method).

在 JVM 调用线程的 run 方法之后,结果就是两个线程同时运行:

  • 当前线程(从调用返回到 start 方法)
  • 另一个线程(执行 run 方法)

一个线程能不能 start 两次?

妹子搞懂了为什么线程一般都使用 start 方法,不使用 run 方法,因为调用的话,就违背了我们想要用多线程去处理的初衷

妹子又问阿粉,那一个线程是不是可以 start 两次呢?

负责任的阿粉赶紧告诉小妹妹是不可以的

如果一个线程启动两次,想都不用想会抛出 IllegalThreadStateException 这个异常

62.jpg

这个错误我们也能在源码中看到:

if (threadStatus != 0)
    throw new IllegalThreadStateException();

线程开始 start 时,会首先判断 threadStatus 的值是否为 0 ,如果值不是 0 的话,说明这个线程的 state 状态不是 new 就抛出 IllegalThreadStateException 异常

啊?竟然还想问阿粉,线程的状态除了 new 还有什么?阿粉以前写过一篇,要不要看看:面试官没想到,一个 Java 线程生命周期,我可以扯半小时

相关文章
|
4月前
|
存储 Java 程序员
优化Java多线程应用:是创建Thread对象直接调用start()方法?还是用个变量调用?
这篇文章探讨了Java中两种创建和启动线程的方法,并分析了它们的区别。作者建议直接调用 `Thread` 对象的 `start()` 方法,而非保持强引用,以避免内存泄漏、简化线程生命周期管理,并减少不必要的线程控制。文章详细解释了这种方法在使用 `ThreadLocal` 时的优势,并提供了代码示例。作者洛小豆,文章来源于稀土掘金。
【多线程面试题 三】、 run()和start()有什么区别?
run()方法定义线程执行的任务,而start()方法启动线程,使得run()在新的线程中异步执行;直接调用run()方法只会同步执行run()中的代码,不会创建新线程。
|
8月前
|
安全 Java
【JAVA】线程的run()和start()有什么区别?
【JAVA】线程的run()和start()有什么区别?
|
8月前
|
安全 Java
面试官:线程调用2次start会怎样?我支支吾吾没答上来
面试官:线程调用2次start会怎样?我支支吾吾没答上来
41 1
|
Java 调度
start()方法和run()方法区别与多线程抢占式运行原理
我们通过一个例子来进行总结,我们写一个利用Thread创建的简单的多线程例子,然后分别执行start()与run()方法,执行结果如下所示:
102 0
|
8月前
|
Java
多线程中的run方法和start方法有什么区别?
多线程中的run方法和start方法有什么区别?
121 0
|
安全 Java API
为什么启动线程不直接调用run(),而要调用start(),如果调用两次start()方法会有什么后果
1位工作6年的小伙伴去某里P6一面,被问到这样一道面试题,说,为什么启动一个线程不直接调用run()方法,而要调用start()方法来启动,如果调用两次start()会有什么后果?
128 0
|
Java
Java线程中的run()和start()区别
Java线程中的run()和start()区别
92 0
|
30天前
|
NoSQL Redis
单线程传奇Redis,为何引入多线程?
Redis 4.0 引入多线程支持,主要用于后台对象删除、处理阻塞命令和网络 I/O 等操作,以提高并发性和性能。尽管如此,Redis 仍保留单线程执行模型处理客户端请求,确保高效性和简单性。多线程仅用于优化后台任务,如异步删除过期对象和分担读写操作,从而提升整体性能。
65 1
|
3月前
|
存储 消息中间件 资源调度
C++ 多线程之初识多线程
这篇文章介绍了C++多线程的基本概念,包括进程和线程的定义、并发的实现方式,以及如何在C++中创建和管理线程,包括使用`std::thread`库、线程的join和detach方法,并通过示例代码展示了如何创建和使用多线程。
72 1