A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 康大玮 中级黑马   /  2012-5-23 22:46  /  3180 人查看  /  14 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

new Thread(
                                new Runnable(){
                                        public void run() {
                                                while(true){
                                                        try {
                                                                Thread.sleep(500);
                                                        } catch (InterruptedException e) {
                                                                e.printStackTrace();
                                                        }
                                                        System.out.println("runnable :" + Thread.currentThread().getName());

                                                }                                                       
                                        }
                                }
                ){
                        public void run() {
                                while(true){
                                        try {
                                                Thread.sleep(500);
                                        } catch (InterruptedException e) {
                                                e.printStackTrace();
                                        }
                                        System.out.println("thread :" + Thread.currentThread().getName());

                                }       
                        }
                }.start();

我有点晕,运行那个run()为什么?

评分

参与人数 1技术分 +1 收起 理由
贠(yun)靖 + 1 这个匿名内部类应该是两个才对啊,感觉错了.

查看全部评分

14 个回复

正序浏览
本帖最后由 袁錦泰 于 2012-5-24 14:35 编辑

你的问题是这个内部类中分既继承Thread类又实现Runnable接口后,在线程执行的时候下面的两个run()方法中执行的是哪个,对吧?我来为你讲解这个问题.
1.创建并启动线程有两种方式,但它们的共性特点都是要调用start()方法后才能真正启动线程,这里只见到一个start()方法,所以可以断定你这里只启动了一条线程.
2.Thread类中的run()方法也是通过实现Runnable接口后得到的,当你继承Thread类后没有复写其run()方法时,就会返回查看父类Thread的run()方法,这时就会去查找实现Runnable接口后的子类run()方法.
3.即便你忘记了上面两点,也可以通过添加输出语句来验证到底是哪个run()方法在执行.
注意:这里的确有两条线程,实现Runnable接口后你的确创建了线程,但是没有启动线程.
第2点可以通过查看源码得到答案,而且楼上那位同学也解释了一下,这一点我可能说的不够清楚,不过没关系,不理解再联系我!

评分

参与人数 2技术分 +1 黑马币 +2 收起 理由
职业规划-刘倩老师 + 1
康大玮 + 2 赞一个!

查看全部评分

回复 使用道具 举报
总算碰到一个没人解答的问题了。。。
如果在构造函数的参数中用runnable对象和继承thread类复写run方法,肯定是调用子类的run方法
因为在子类的run方法里面有这么一句 if(target!=null) return target,指的就是runnable,也就是说调用runnable的原理就是你如果使用thread类的run方法才会去调用,
但是你复写了thread的run方法,所以不会去调用到runnable的run方法,不知道lz明不明白
如果还不明白的话,建议你看一下张孝祥老师的多线程并发技术的视频,里面解释的很清楚,直接上源码解释的。

点评

3Q  发表于 2012-5-24 20:41

评分

参与人数 2技术分 +1 黑马币 +2 收起 理由
职业规划-刘倩老师 + 1
康大玮 + 2 赞一个!

查看全部评分

回复 使用道具 举报
贠(yun)靖 发表于 2012-5-24 12:41
等毕业还得等1年呢 - -  大四直接请假就去了

嗯。羡慕啊,要是我去的时候 黑马都快二十几期了。唉。先毕业再说吧
回复 使用道具 举报
谭威 发表于 2012-5-24 12:32
那你是不是等毕业后去黑马啊,我大二啊,还这么长时间。

等毕业还得等1年呢 - -  大四直接请假就去了  
回复 使用道具 举报
贠(yun)靖 发表于 2012-5-24 12:29
大三,基本不用上课了

那你是不是等毕业后去黑马啊,我大二啊,还这么长时间。
回复 使用道具 举报
谭威 发表于 2012-5-24 12:28
问下版主们,你们怎么天天在线,你们不上课了么,不上班么

大三,基本不用上课了
回复 使用道具 举报
谭威 中级黑马 2012-5-24 12:28:19
9#
贠(yun)靖 发表于 2012-5-24 12:25
new Thread(
                                new Runnable(){
                                         ...

问下版主们,你们怎么天天在线,你们不上课了么,不上班么:o
回复 使用道具 举报
new Thread(
                                new Runnable(){
                                        public void run() {
                                                while(true){
                                                        try {
                                                                Thread.sleep(500);
                                                        } catch (InterruptedException e) {
                                                                e.printStackTrace();
                                                        }
                                                        System.out.println("runnable :" + Thread.currentThread().getName());

                                                }                                                        
                                        }
                                }.start());
                     
   new Thread(new Runnable(){
               public void run() {
                                while(true){
                                        try {
                                                Thread.sleep(500);
                                        } catch (InterruptedException e) {
                                                e.printStackTrace();
                                        }
                                        System.out.println("thread :" + Thread.currentThread().getName());

                                }        
                        }
                }.start());              应该这样写   两个线程,分别都用两个匿名内部类启动线程
回复 使用道具 举报
你这是一个内部类,实现多线程要复写run()方法,但是只有一个run()方法可以复写,你去看看API哪有两个run()方法啊。


PS:你的代码写的很不好读,建议你以后写代码写的好看点,一行一行的要有层次感,养成一个好习惯很重要的!
  以后代码多了你自己看的都会头痛。
回复 使用道具 举报
楼主 你先要明白多线程为什么会产生啊?因为要同时执行某些任务,所以创建多个线程。

同时为了提高程序的扩展性,将一些需要同时运行的代码进行封装。
让这个类实现一个接口,并在该接口中复写成自己想要运行的程序,然后通过线程直接让它自动去调用 所有实现这个接口的代码 实现程序的自定义。
而那个run方法就是接口上已有的,同时也是自定义代码所要复写的方法。

我是这样理解的 希望多楼主有些帮助~
回复 使用道具 举报
上面代码可以这样看 ,首先创建了一个匿名的 new Thread(){}
然后创建了一个 new Runnable() {} ,所以会先执行new Thread (){}, 如果没有则执行new  Runnable(){} 。
回复 使用道具 举报
大量的程序需要执行,但是一行一行执行代码,效率很低,为了让很多程序可以互不影响的同时执行,多线程就应运而生了
线程就是为了执行程序的,但是一个线程它怎么能知道它要执行哪些呢?于是就有了run(),run就告诉线程,来把,我里面装的就是你要执行的代码
从此,线程就只认识run()方法了。你要想执行什么代码,就把那些代码交给run()方法,线程要工作就去找run()方法干活去了

哈哈,例子不是很恰当,应该会能够帮你理解把
回复 使用道具 举报
创建多线程的2种方式:
1、一个是继承Thread类,改写run()方法,在main中使用  对象名.start()是run运行
2、实现runnable接口,同样需要改写run()接口,
这种形式的 多线程容易出错,所以最好还是加上synchronised 同步方法,
回复 使用道具 举报
实现多线程,要实现Runnable接口,并覆盖其run方法,run方法中就是线程执行的代码
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马