繁体   English   中英

由runnable构造的线程对象会覆盖run方法

[英]Thread object constructed by runnable overrides the run method

鉴于此示例代码:

Runnable r = new Runnable() {
  public void run() {
    System.out.print("Cat");
  }
};
Thread t = new Thread(r) {
  public void run() {
    System.out.print("Dog");
  }
};
t.start();

为什么输出狗而不是猫?

run in Thread的实现只是调用构造函数中提供的Runnable (如果有的话)。 您正在覆盖该代码,因此如果新线程只是调用其run方法,则忽略Runnable 当然,您应该能够查看源代码来检查...(我刚刚这样做了,虽然我不打算在这里发布源代码,但它完全按照我的描述进行。)

你真正暴露的是封装问题 - Thread 不应该有这些不同的,可能相互矛盾的方式来说明线程应该做什么。 基本上,你几乎应该直接扩展Thread 仅仅因为它设计得很糟糕并不意味着你必须滥用那种糟糕的设计;)

编辑:这实际上是以一种稍微迂回的方式记录的。 start()记录为:

导致此线程开始执行; Java虚拟机调用此线程的run方法。

run()记录为:

如果使用单独的Runnable运行对象构造此线程,则调用该Runnable对象的run方法; 否则,此方法不执行任何操作并返回。

因此run()方法按照start()调用,但是你重写了run() ,这是调用构造函数中提供的Runnable唯一方法。

请注意,如果您重写了这样的方法:

Thread t = new Thread(r) {
  public void run() {
    super.run();
    System.out.print("Dog");
  }
};

然后输出将是“CatDog”。

您已重写Thread.run以便它不执行runnable。 相反,它只是打印“狗”。

这是因为函数run()被覆盖了。 t调用这个函数:

public void run() {
System.out.print("Dog");
}

当你执行r.start()时,你将获得o / p作为cat ,这将调用该函数

 public void run() {
    System.out.print("Cat");
  }

看一下java.lang.Thread的源代码:

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

targetThread(Runnable)构造函数用于分配r变量的Thread中的Runnable字段。 当你在Thread覆盖run方法时,你正在改变run to call的行为

System.out.print("Dog");

而不是打电话

if (target != null) {
    target.run();
}

这是一个匿名类,您正在重新定义/覆盖run 你在run使用传入的Runnable吗? 不,你没有。 所以问题是,你为什么期望它打印Cat

 new Thread(r) {
  public void run() {
    System.out.print("Dog");
  }
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM