run()会选runnable中的还是Thread中的 - SCJP考题求助
题1:
Given:
11. Runnable r = new Runnable() {12. public void run() {13. System.out.print("Cat");14. }15. };16. Thread t = new Thread(r) {17. public void run() {18. System.out.print("Dog");19. }20. };21. t.start();1. public class Threads5 {2. public static void main (String[] args) {3. new Thread(new Runnable() {4. public void run() {5. System.out.print("bar");6. }}).start();7. }8. } /* What will be run. */ private Runnable target; public void run() { if (target != null) { target.run(); } }
[解决办法]
这个你要看JDK的源码实现(jdk安装目录下有个src.zip):
public
class Thread implements Runnable {
…………
private Runnable target; //保存初始化时传入的实现Runnable接口的对象
……………………………………
}
看他的start和run方法实现:
public synchronized void start() {
if (threadStatus != 0)
throw new IllegalThreadStateException();
group.add(this);
start0();
if (stopBeforeStart) {
stop0(throwableFromStop);
}
}
start实际上是去调用start0()(native method),由其去调用run方法。再看Thread类的run实现:
public void run() {
if (target != null) {
target.run();
}
}
那么第一题很好理解了,因为你override了Thread的run方法,所以不会去调用target Runnable的run方法,所以输出Dog;第二题当然输出bar,因为初始化Thread时传入了用匿名内部类实现Runnable接口的对象,所以target不为null,而本身的run方法没有override,所以就会调用该匿名内部类(即target Runnable)实现的run方法。
[解决办法]
看下源码就知道了,Thread里有成员变量Runnable target,当构造函数的参数有Runnable时就会把target赋值为参数,Thread的run方法会判断target是否为null,不为null就调用target的run方法
如果重写了Thread的run方法并不调用super.run();,那target的run方法自然就不会再被调用了
[解决办法]
显然是不喜欢看API的楼主。。