[英]Thread object constructed by runnable overrides the run method
Given this sample code: 鉴于此示例代码:
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();
why is the output Dog and not Cat?? 为什么输出狗而不是猫?
The implementation of run
in Thread
simply calls the Runnable
provided in the constructor, if there is one. run
in Thread
的实现只是调用构造函数中提供的Runnable
(如果有的话)。 You're overriding that code, so if the new thread simply has its run
method called regardless, the Runnable
is ignored. 您正在覆盖该代码,因此如果新线程只是调用其
run
方法,则忽略Runnable
。 Of course, you should be able to look at the source code to check that... (I've just done so, and while I'm not going to post the source here, it does exactly what I've described.) 当然,您应该能够查看源代码来检查...(我刚刚这样做了,虽然我不打算在这里发布源代码,但它完全按照我的描述进行。)
What you've really exposed is an encapsulation problem - Thread
shouldn't have these different, potentially conflicting, ways of saying what the thread should do. 你真正暴露的是封装问题 -
Thread
不应该有这些不同的,可能相互矛盾的方式来说明线程应该做什么。 Basically, you should almost never extend Thread
directly. 基本上,你几乎不应该直接扩展
Thread
。 Just because it's been designed badly doesn't mean you have to abuse that poor design ;) 仅仅因为它设计得很糟糕并不意味着你必须滥用那种糟糕的设计;)
EDIT: This is actually documented, in a somewhat roundabout way. 编辑:这实际上是以一种稍微迂回的方式记录的。
start()
is documented as: start()
记录为:
Causes this thread to begin execution;
导致此线程开始执行; the Java Virtual Machine calls the run method of this thread.
Java虚拟机调用此线程的run方法。
And run()
is documented as: run()
记录为:
If this thread was constructed using a separate Runnable run object, then that Runnable object's run method is called;
如果使用单独的Runnable运行对象构造此线程,则调用该Runnable对象的run方法; otherwise, this method does nothing and returns.
否则,此方法不执行任何操作并返回。
So the run()
method is called as per start()
, but you've overridden run()
, which is the only method which will call the Runnable
provided in the constructor. 因此
run()
方法按照start()
调用,但是你重写了run()
,这是调用构造函数中提供的Runnable
的唯一方法。
Note that if you'd overridden the method like this: 请注意,如果您重写了这样的方法:
Thread t = new Thread(r) {
public void run() {
super.run();
System.out.print("Dog");
}
};
Then the output would be "CatDog". 然后输出将是“CatDog”。
You have overridden Thread.run
so that it doesn't execute the runnable. 您已重写
Thread.run
以便它不执行runnable。 Instead it just prints "Dog". 相反,它只是打印“狗”。
It is because the function run()
is overridden. 这是因为函数
run()
被覆盖了。 And t
call this function: 而
t
调用这个函数:
public void run() {
System.out.print("Dog");
}
You will get the o/p as cat
when you execute r.start()
Which will call the function 当你执行
r.start()
时,你将获得o / p作为cat
,这将调用该函数
public void run() {
System.out.print("Cat");
}
Taking a look at the source code for java.lang.Thread
: 看一下
java.lang.Thread
的源代码:
public void run() {
if (target != null) {
target.run();
}
}
target
is the Runnable
field in the Thread
that the Thread(Runnable)
constructor uses to assign your r
variable. target
是Thread(Runnable)
构造函数用于分配r
变量的Thread
中的Runnable
字段。 When you override the run
method in the Thread
, you're changing the behavior of run
to call 当你在
Thread
覆盖run
方法时,你正在改变run
to call的行为
System.out.print("Dog");
instead of calling 而不是打电话
if (target != null) {
target.run();
}
This is an anonymous class and you are redefining/overriding run
. 这是一个匿名类,您正在重新定义/覆盖
run
。 Are you using the passed-in Runnable
inside your run
? 你在
run
使用传入的Runnable
吗? No you don't. 不,你没有。 So the question is, why did you expect it to print
Cat
? 所以问题是,你为什么期望它打印
Cat
?
new Thread(r) {
public void run() {
System.out.print("Dog");
}
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.