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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

强文何

黑马帝

  • 黑马币:0

  • 帖子:18

  • 精华:0

© 强文何 黑马帝   /  2012-5-17 14:11  /  1588 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

我一直有这样的一个疑问:在创建线程的时候,重写了父类的run()方法,但是不是构造方法。使用时为什么不是使用对象名.run()的形式?它内部的实现原理是什么?我找了java的源代码发现没有?它只是一个抽象类。

5 个回复

倒序浏览
你能把代码贴出来吗,这样有益于解答。
回复 使用道具 举报

创建线程有两个方法
1.继承Thread类
                定义类继承Thread, 重写run()方法, 将线程中要执行的代码写在run()方法中
                创建该类对象, 调用start()方法就可以开启一条新线程, 新线程中自动指定run()方法
2.实现Runnable接口
                定义类实现Runnable接口, 重写run()方法, 将线程中要执行的代码写在run()方法中
                创建该类对象, 创建Thread类对象, 将Runnable对象传入Thread的构造函数中
                调用Thread对象的start()方法就可以开启一条新线程, 新线程中执行Runnable的run()方法
回复 使用道具 举报
任何一个线程的启动最终都需要经过某个Thread实例的start()方法,通过一个实现了Thread类的具体实例的构造方法或是通过调用run()方法并不意味着开启了新的线程
回复 使用道具 举报
本帖最后由 袁冬梅 于 2012-5-17 18:07 编辑

我简单看了一下源码,我也不是很懂喔,不过我可以帮你解一点疑惑

首先在创建线程的时候,重写了父类的run()方法,但是不是构造方法。使用时为什么不是使用对象名.run()的形式?
看到Thread类源码中有这样一句话group.add(this);
  1.     public synchronized void start() {
  2.         if (threadStatus != 0)
  3.             throw new IllegalThreadStateException();
  4.      group.add(this);
  5.      start0();
  6.         if (stopBeforeStart) {
  7.             stop0(throwableFromStop);
  8.         }
  9.     }
复制代码
然后我发现,这句话就是创建了一个新的线程,你可以去ThreadGroup类中查看void add(Thread t) 这个方法,就发现它在线程族里面新添加一个线程进去,所以,在Thread在进行start的时候是创建了一个新的线程,而你说的构造函数,我看了一下,构造函数做的工作其实只是对一个新创建出来的Thread进行初始化工作,而没有把这个线程对象加入线程族中,那么就说明此时新线程其实是没有创建出来的。

然后,你说的使用  对象.run()吧,你看你直接用了Thread的你自己创建的对象使用run,但是,你没有经过start把你创建好的Thread对象加入线程组里面,那么它运行起来的时候就不是一个新线程。怎么说呢?你看下面的代码,我帮你做了一个小小的测试,希望能帮助到你理解线程的创建
  1.         Thread t = new Thread(){
  2.                 @Override
  3.                 public void run() {
  4.                         System.out.println("复写父类的run方法");
  5.                         System.out.println("此时run方法是在"+Thread.currentThread().getName()+"线程里面运行");
  6.                 }
  7.         };
  8.         t.run();        //检测通过对象直接调用run方法运行的时候,run方法是在哪个线程中运行
  9.         t.start();   //检测start方法创建了线程之后,run方法是在哪个线程中运行
  10. /*结果:
  11. 复写父类的run方法
  12. 此时run方法是在main线程里面运行
  13. 复写父类的run方法
  14. 此时run方法是在Thread-0线程里面运行*/
复制代码
回复 使用道具 举报
额,忘记说了,第二段代码我是放在main方法中的,你要试验的话也要把代码放在main方法中哈
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马