启动线程时使用 start 而不是 run

今天团队里面的妹子问阿粉,为什么在启动线程的时候,都使用 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());
    }
}

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

你会发现, 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 这个异常

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

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

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

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

快来关注我,每天会有非常精彩的文章放出,回复算法宝典,送资源,电子书,面试获取面试宝典
在这里插入图片描述

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值