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. You're overriding that code, so if the new thread simply has its run
method called regardless, the Runnable
is ignored. 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. Basically, you should almost never extend Thread
directly. 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:
Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread.
And run()
is documented as:
If this thread was constructed using a separate Runnable run object, then that Runnable object's run method is called; 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.
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".
You have overridden Thread.run
so that it doesn't execute the runnable. Instead it just prints "Dog".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With