创建Thread对象时,当Runnable的run撞上Thread的run时谁会让步?

问题原型

文章题目说的有些文艺,所提的问题就是,运行如下代码,输出的结果是什么?(PS:不要怀疑问题,我保证如下代码没有任何语法错误)。

new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("Runnable-->run");
    }
}) {
    @Override
    public void run() {
        System.out.println("Thread-->run");
    }
}.start();

答案揭晓

如上代码的运行后输出:Thread–>run,上图说真相:
这里写图片描述

为什么会这样?

遇到这种问题时,源码总能给我们最好的答案,所以,下面就从源码中找出为什么?
在看源码前,该思考要从源码的哪部分看起?如上的代码,总共涉及源码中的三部分,如下

  1. Thread类以Runnable对象作为参数的构造器;
  2. Thread类的Run方法的实现;
  3. Thread类的start方法的实现。

我从第三点切入,深入源码一探究竟。(注:我读的是 JDK1.8.0_60 的源码)。

  • Thread 的 start()方法的实现如下:
    这里写图片描述
    重点是调用了 start0()这个方法,继续追踪该方法:

  • start0()方法的声明如下:
    这里写图片描述
    看到该方法是个native方法,它的实现应该在JVM中。该方法无法继续追踪,转而看看Thread的run()方法:

  • Thread的run()方法实现如下:
    这里写图片描述
    结合方法的注释,并在源码中追查一下target变量的含义,不难发现这个target对象,就是用Thread的构造器创建对象时传进来的Runnable对象,而Thread的run方法的功能是,先判断target是否为null,如果不为null就调用target的run()方法。这时,谜团已经有了眉目了——用Runnable对象创建Thread对象时传递进来的Runnable对象的run()方法,是依靠Thread的run()方法的调用才得以执行。对于我们的问题,如上代码所示,我们在Thread子类中直接重写了run方法,Runnable对象的run方法没地方被调用,因此就没有执行的可能了。所有运行结果就如上所示。

  • 那么,问题来了:Thread的run()方法又是在哪里被调用的呢?在start()方法中并没有看到run()方法被调用啊?
    继续从源码中找答案:看看start方法的注释,有这么一句,如下图中划横线的这句:
    这里写图片描述
    它的意思是:“jvm会调用这个线程的run方法”此时就清楚了,也就可以肯定,在上面的提到的start0()方法是在JVM中实现的,JVM通过start0()这个方法调用了Thread的run方法。

至此,所提问题得到解答。


拓展延伸

如果代码是如下的样子,结果又是什么呢?

new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("Runnable-->run");
    }
}) {
    @Override
    public void run() {
        super.run(); // 相比原问题,多了这一句
        System.out.println("Thread-->run");
    }
}.start();

结果输出是:
Runnable–>run
Thread–>run
对于这个结果的解释,根据如上的原理剖析,读者应该心中有数了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值