鉴于此示例代码:
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();
为什么输出Dog而不是Cat ??
答案 0 :(得分:7)
run
中Thread
的实施只会调用构造函数中提供的Runnable
(如果有)。您正在覆盖该代码,因此如果新线程只是调用其run
方法,则忽略Runnable
。当然,您应该能够查看源代码来检查...(我刚刚这样做了,虽然我不打算在这里发布源代码,但它完全按照我的描述进行。)
你真正暴露的是封装问题 - Thread
不应该有这些不同的,可能相互矛盾的方式来说明线程应该做什么。基本上,你几乎永远不会直接扩展Thread
。仅仅因为它设计得很糟糕并不意味着你必须滥用那种糟糕的设计;)
编辑:这实际上是以一种稍微迂回的方式记录的。 start()
记录为:
使该线程开始执行; Java虚拟机调用此线程的run方法。
run()
记录为:
如果使用单独的Runnable运行对象构造此线程,则调用该Runnable对象的run方法;否则,此方法无效并返回。
因此,run()
方法按start()
调用,但您已覆盖run()
,这是唯一方法,它将调用{{} 1}}在构造函数中提供。
请注意,如果你覆盖了这样的方法:
Runnable
然后输出将是“CatDog”。
答案 1 :(得分:3)
您已覆盖Thread.run
,因此它不会执行runnable。相反,它只是打印“狗”。
答案 2 :(得分:0)
这是因为覆盖了函数run()
。 t
调用此函数:
public void run() {
System.out.print("Dog");
}
当您执行cat
时,您将获得r.start()
的o / p将调用该函数
public void run() {
System.out.print("Cat");
}
答案 3 :(得分:0)
查看java.lang.Thread
的源代码:
public void run() {
if (target != null) {
target.run();
}
}
target
是Runnable
中的Thread
字段,Thread(Runnable)
构造函数用于分配r
变量。当您覆盖run
中的Thread
方法时,您正在更改run
的行为以致电
System.out.print("Dog");
而不是打电话
if (target != null) {
target.run();
}
答案 4 :(得分:-1)
这是一个匿名类,您正在重新定义/覆盖run
。您是否在Runnable
内使用了传入的run
?不,你没有。所以问题是,为什么你希望它打印Cat
?
new Thread(r) {
public void run() {
System.out.print("Dog");
}
};