黑马程序员技术交流社区

标题: 【哈尔滨校区】多线程中Runnable的run和Thread的run [打印本页]

作者: JavaDeveloper    时间: 2017-11-29 15:27
标题: 【哈尔滨校区】多线程中Runnable的run和Thread的run
new Thread(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("Runnable-->run");
                    }
                }) {
                    @Override
                    public void run() {
                        System.out.println("Thread-->run");
                    }
                }.start();
先解释一下这个代码,可能有的同学已经忘了匿名内部类的使用和创建!
创建一个Thread的子类对象并重写Thread的run()方法,通过Thread的子类对象的构造方法传递一个Runnable接口的实现类对象并重写Runnable接口的run()方法!
输出结果是: Thread-->run
为什么执行的是Thread子类的run(),难道不应该是Runnable接口实现类对象的run()吗?
接下来看Thread的源码
public void run() {
        if (target != null) {
            target.run();
        }
    }

target哪来的呢,其实就是Thread的构造方法传递的Runnable接口的实现类对象,源码意思说如果传递的实现类对象不为空则调用实现类对象的run方法,那么为什么结果调用的却是Thread子类对象的run(),那是因为源码中有判断是否为空,不为空调用Runnable的run(),结果我们的代码是重写了Thread的run方法,所以执行的结果就是Thread的run方法!
接下来有个问题,如果是以下代码,执行的结果会是什么呢???
new Thread(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("Runnable-->run");
                    }
                }) {
                    @Override
                    public void run() {
                        super.run();
                        System.out.println("Thread-->run");
                    }
                }.start();

有了对第一个案例的理解,这个就比较好理解了!
重写Thread的run()方法,并在第一行调用了父类的run();父类的run()是执行了Thread()的构造中传递过来的Runnable接口的实现类对象的run方法,所以先执行Runnable的run(),然后执行System.out.println("Thread-->run");
结果就是:
Runnable-->run   
Thread-->run




作者: synchronize    时间: 2017-11-29 23:51

public class TestDemo {

        public static void main(String[] args) {
                TestRunnable tr = new TestRunnable();
                TestThread test = new TestThread(tr);
                test.start();
        }
}

class TestThread extends Thread {

        @Override
        public void run() {
                super.run();
                System.out.println("Thread-->run");
        }

        public TestThread(Runnable target) {
                super(target);
        }
}

class TestRunnable implements Runnable {

        @Override
        public void run() {
                System.out.println("Runnable-->run");
        }
}

完全体?
作者: 桃染朱砂    时间: 2017-11-30 10:17
虽然看不懂到但是觉得好厉害的样子啊
作者: 桃染朱砂    时间: 2017-11-30 10:20
虽然看不懂到但是觉得好厉害的样子啊
作者: 张斯佳    时间: 2017-11-30 10:22
居然还简单的说了一下源码,你们现在不建议看太深的源码,简单看看就行了,加油 你们是最棒的
作者: 杨露露老师    时间: 2017-11-30 16:00
加油 你们是最棒的
作者: 黑马与你同在    时间: 2017-11-30 16:16
很不错 。

作者: 董国洋_    时间: 2017-12-2 10:21
一语惊醒梦中人, 贼酷!
作者: 呵呵哈哈256    时间: 2017-12-2 10:23
写的很好!简洁易懂
作者: zhanzuhui    时间: 2017-12-2 10:30
说的很不错,不过看的我还是优点懵逼
作者: 峨眉山吴彦祖    时间: 2017-12-2 10:34
说实话,理解不了这位大神再说什么,有空再研究研究吧.
作者: sxnacm    时间: 2017-12-2 10:35
详细又不啰嗦,直击重点!
作者: 刘昌昊    时间: 2017-12-2 13:12
看了很久,第一个是我们重写的Thread run方法将源码中的覆盖了,第二个通过super调用没有被覆盖,这理解不知道对不对
作者: ycbin    时间: 2017-12-2 15:03
看了好久终于看懂了,太难了,感觉自己的逻辑能力严重欠缺
作者: 恋爱不如敲代码    时间: 2017-12-2 17:28
第一个看懂了 第二个的话看不太明白啊
作者: 学员123    时间: 2017-12-2 17:42
格式工整  思路清晰  如果加上注释就完美
作者: weiyipeng123456    时间: 2017-12-2 17:48
写的很好简单也能看的懂
作者: 天敬沅    时间: 2017-12-2 18:26
虽然看不懂,但是还是非常牛啊 向你学习
作者: 为学日益者    时间: 2017-12-2 19:15
写的很好!谢谢分享!
作者: 聆听者    时间: 2017-12-2 19:17
翻了多少笔记,看了多少Demo,才看得懂这括号和换行,才明白佳哥的话:不复习真的会忘,而且会忘得很干净······
作者: Lust    时间: 2017-12-2 20:07
说实话,看不懂。学的多,用的少,忘的快是我现在最大的学习问题,此贴我就复制保存了。感谢分享!
作者: Lust    时间: 2017-12-2 20:13
好吧,看不懂。学的多,用的少,忘得快是我现在学习上的最大问题。此贴以复制保存,谢谢分享!
作者: 默契人生    时间: 2017-12-2 20:40
有点没明白,是两个内部类吗,那是不是在thread后应该还有一个小括号啊?
作者: 默契人生    时间: 2017-12-2 20:42
有点没看明白,是两个内部类吗那是不是在thread就还应该有一个小括号啊?
作者: 默契人生    时间: 2017-12-2 20:45
有点没明白啊,是两个内部类吧,那是不是thread后还应该有一个小括号啊?
作者: 13654406079    时间: 2017-12-2 20:55
加油!很棒
作者: 敲代码---    时间: 2017-12-2 21:15
synchronize 发表于 2017-11-29 23:51
public class TestDemo {

        public static void main(String[] args) {

看到大神写的东西,才知道差距这么大,还是得好好学习啊,勤复习,多练习,少扯皮,争取紧跟大神步伐!!!
作者: 爱奋斗的桃花侠    时间: 2017-12-2 21:29
子类重写父类方法后创建子类对象调用的当然是子类重写的法啊。。。
作者: lin632854170    时间: 2017-12-2 21:37
现在看这个有些费劲 可能是那时候记得不够扎实 ,思路有点绕,勉强能够看懂!!!!!
作者: 王瑞楠    时间: 2017-12-2 21:48
看了小明班长写的这个,感觉之前都是按照格式来巧代码,不过这个还真是看不太懂,尽管小明班长给讲了一遍,但是也只是知道一点点,想真的明明白白,感觉还不是一时半会儿的事啊
作者: 黑胡子爷爷    时间: 2017-12-2 22:37
回顾了一下以前学 的知识 很棒  虽然有些都快忘光了还带先翻一下笔记
作者: 黑胡子爷爷    时间: 2017-12-2 22:58
说的很棒 回顾了一下以前的学的知识 ,虽然都忘的快没了  现翻的笔记 看的
作者: 黑胡子爷爷    时间: 2017-12-2 23:02
回顾了以前的学的知识  虽然都快忘光了 还是很棒
作者: 刘汉国    时间: 2017-12-2 23:17
两个匿名内部类,Runnable的内部类当做参数来传递,学到了
作者: 小鹿哥    时间: 2017-12-2 23:54
嗯?嗯?嗯?,一脸懵逼...
作者: Vampire军哥    时间: 2017-12-3 00:05
刚学过的都忘记了,看了之后,算是复习也更是加深理解
作者: 骑士冈布奥    时间: 2017-12-3 00:43
每天复习一点点,掌握的就牢一些,又学到了,感谢
作者: sunyiran    时间: 2017-12-3 11:06
简单的说,Thread 传入了Runnable匿名对象时,重写Run方法,并作为覆盖自身run方法,而后创建匿名子类对象,又覆盖run方法
作者: 15846125943    时间: 2017-12-5 10:51
不亏是大腿   没全看明白
作者: pyx0812    时间: 2017-12-5 13:14
第一遍看的时候居然看不太懂,看来应该好好复习一下啦
作者: adonispeng    时间: 2017-12-5 22:02
写的真好 ,对我的学习非常有帮助

作者: JavaDeveloper    时间: 2017-12-5 22:02
synchronize 发表于 2017-11-29 23:51
public class TestDemo {

        public static void main(String[] args) {

差不多,单独写类就是这样的
作者: 陈鑫-    时间: 2017-12-5 23:01
看着对自己很有帮助




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2