Java来看一道多线程面试题
问题:下面线程开启后会执行哪一句话会输出到控制台?
答:你好Thread 会被打印
public static void main(String[] args) { Runnable runnable = new Runnable() { @Override public void run() { System.out.println("你好Runable"); } }; new Thread(runnable) { @Override public void run() { System.out.println("你好Thread"); } }.start(); }
解读
Runnable runnable = new Runnable() { @Override public void run() { System.out.println("你好Runable"); } };
上面的代码使用了匿名内部类的方式实现了Runnable接口,并用父类引用指向子类对象------多态。总之表示创建了Runnable接口实现类对象runnable。
new Thread(runnable)
使用有参构造创建Thread对象,也采用了匿名内部类实现。
new Thread(runnable) { @Override public void run() { System.out.println("你好Thread"); } }.start();
这里表示匿名类的子类,因为有大括号重写,就表示子类。最终要的就是后面的start方法了。线程对象调用start对象后,操作系统(start方法底层调用了c语言我们暂时是看不到源码)会为我们调用线程的run方法,我们来看有参构造的执行流程。
我们发现最后Runnable接口实现类对象传递给了Thread的成员变量,我们现在再来看看操作系统为我们调用的run方法。
如果刚刚传递过去的Runnable接口实现类对象不为空,那么执行它的run();方法。以上就是有参Thread构造方法和start方法执行流程。
再回到面试题
new Thread(runnable) { @Override public void run() { System.out.println("你好Thread"); } }.start();
我们发现Thread类中的run方法已经被重写,所以即使传递了runnable,也没有用,最后开启线程,执行了System.out.println(“你好Thread”);
思考
那么如何执行runnable里面的代码呢?手动执行就行了呗
new Thread(runnable) { @Override public void run() { runnable.run(); System.out.println("你好Thread"); } }.start();
或者我们调用一下父类有参构造里面的run方法也可以
new Thread(runnable) { @Override public void run() { super.run(); System.out.println("你好Thread"); } }.start();
运行结果
你好Runable你好Thread
赞 (0)