妹子问我为啥启动线程时使用 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 线程生命周期,我可以扯半小时

相关文章
|
1月前
|
安全 Java
【JAVA】线程的run()和start()有什么区别?
【JAVA】线程的run()和start()有什么区别?
|
10月前
|
Java 调度
start()方法和run()方法区别与多线程抢占式运行原理
我们通过一个例子来进行总结,我们写一个利用Thread创建的简单的多线程例子,然后分别执行start()与run()方法,执行结果如下所示:
66 0
|
1月前
|
Java
多线程中的run方法和start方法有什么区别?
多线程中的run方法和start方法有什么区别?
|
9月前
|
安全 Java API
为什么启动线程不直接调用run(),而要调用start(),如果调用两次start()方法会有什么后果
1位工作6年的小伙伴去某里P6一面,被问到这样一道面试题,说,为什么启动一个线程不直接调用run()方法,而要调用start()方法来启动,如果调用两次start()会有什么后果?
78 0
|
Java
Java线程中的run()和start()区别
Java线程中的run()和start()区别
69 0
|
存储 Java 编译器
进程和线程的区别&&run和start区别与联系
进程和线程的区别&&run和start区别与联系
|
安全 Java
【Java|多线程与高并发】详解start()方法和run()方法的区别
本篇文章主要讲解以下几个问题:start()方法和run()方法的区别与联系 为什么不能连续两次调用shart()方法 run()方法中可能忽略的问题
|
3天前
|
存储 测试技术
【工作实践(多线程)】十个线程任务生成720w测试数据对系统进行性能测试
【工作实践(多线程)】十个线程任务生成720w测试数据对系统进行性能测试
10 0
【工作实践(多线程)】十个线程任务生成720w测试数据对系统进行性能测试
|
4天前
|
数据采集 Java Unix
10-多线程、多进程和线程池编程(2)
10-多线程、多进程和线程池编程
|
4天前
|
安全 Java 调度
10-多线程、多进程和线程池编程(1)
10-多线程、多进程和线程池编程