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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© Teemo_Mann 中级黑马   /  2014-4-17 19:48  /  1959 人查看  /  8 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

我有个疑问,集成Runnable接口的类,再通过Thread类创建线程,为什么this不是指调用start方法的thread对象,而是实现Runnable的类的对象呢?如果是指下面的这个Threst对象,那多个对象如何区分呢
  1. class Threst implements Runnable{
  2.         private int sum = 100;
  3.         @Override
  4.         public void run() {
  5.                 // TODO Auto-generated method stub
  6.                 while(true){
  7.                         if(sum > 0){
  8.                                 try {
  9.                                         Thread.sleep(10);
  10.                                 } catch (InterruptedException e) {
  11.                                         // TODO Auto-generated catch block
  12.                                         e.printStackTrace();
  13.                                 }
  14.                                 System.out.println(Thread.currentThread().getName() + "  " + (sum--));
  15.                                 System.out.println(this.getClass());  //这里的this为什么不是Thread对象
  16.                         }else{
  17.                                 break;
  18.                         }
  19.                 }
  20.         }
  21.        
  22. }
复制代码

  1. public class ThreadTest {

  2.         public static void main(String[] args) {
  3.                 // TODO Auto-generated method stub
  4.                 Threst thr = new Threst();
  5.                 Thread th1 = new Thread(thr);
  6.                 Thread th2 = new Thread(thr);
  7.                 th1.start();   //这个地方明明是th1调用的start方法,为什么上面的this却是Threst
  8.                 th2.start();
  9.         }

  10. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
SyouRai_Tsk + 1

查看全部评分

8 个回复

倒序浏览
public Thread(Runnable target),来看构造函数,参数说明已经说出了调用的是你传入的类的run方法,既然是传入的类的run方法,你程序中传入的是Threst类,那么当然this就是Threst了
参数:
target - 其 run 方法被调用的对象。

评分

参与人数 1技术分 +1 收起 理由
itpower + 1

查看全部评分

回复 使用道具 举报
要学会看API了同学,不然以后做程序多痛苦啊
回复 使用道具 举报
本帖最后由 执笔梦 于 2014-4-17 21:37 编辑

虽然是 th1调用了start()方法,启动线程,但是执行run()方法是却是Threst 的run()方法;
所有this.代表Threst 的对象,求技术分...:'(

评分

参与人数 1技术分 +1 收起 理由
itpower + 1

查看全部评分

回复 使用道具 举报
Runnable是一个接口,不能初始化对象。Runnable接口的实现类对象重写了Runnable类的run方法,但是run方法是不能开启线程的。Thread类的一个构造方法能够用Runnable接口的子类对象初始化线程对象,并且调用的仍然是接口子类对象当中的run方法,run方法中使用的对象仍然是Runnable子类对象,所以this是指Threst对象而不是Thread的对象

评分

参与人数 1技术分 +1 收起 理由
itpower + 1

查看全部评分

回复 使用道具 举报
首先地明确一点,Threst是通过imolements Runnable 类来实现线程的,而Runnable 中并没有run()方法,代码中实现的run()方法是Threst类中定义的,所以想要实现它必定就得用该类对象调用,故此处的this只的是Threst的对象。
回复 使用道具 举报
muma 中级黑马 2014-4-17 23:11:56
7#
  1. public class ThreadTest {

  2.         public static void main(String[] args) {
  3.                 // TODO Auto-generated method stub
  4.                 Threst thr = new Threst();
  5.                 Thread th1 = new Thread(thr);
  6.                 Thread th2 = new Thread(thr);
  7.                 th1.start();   //th1调用了start()方法,启动线程并调用run()方法执行,但是该fun方法却是Threst 的run方法;所以this.代表Threst 的对象
  8.                 th2.start();
  9.         }

  10. }
复制代码
回复 使用道具 举报
本帖最后由 也许依然 于 2014-4-19 16:34 编辑

    java中实现多线程的应用有两种途径,一种是用Thread类的子类创建线程,另一种是用Thread类创建线程。
Thread类综合了java程序中一个线程需要拥有的属性和方法,主要有:
构造方法,start(), run()等
    当编写Thread的子类时,可以在子类中重写父类的run()方法,该方法中包含了线程的操作。这样程序在创建自己的线程时,只需要创建一个已定义好的Thread子类实例就好了。
    Runnable是一个接口,该接口只有一个方法run(),所有实现Runnable接口的类都必须具体实现这个run()方法,为它提供方法体,并定义基本操作。当用Thread类的构造方法 public Thread(Runnable target)创建线程对象时,构造方法中的参数必须是一个具体的对象,该对象称作线程的目标对象,创建线程目标对象的类必须实现Runnable接口。当线程调用start()方法时,一旦轮到它来享用CPU,目标对象就会自动调用接口中的run()方法。所以一个实现了Runnable接口的类实际上定义了一个主线程之外的新线程操作。

    1 当一个Thread类或其子类对象被声明,并创建时,新生的线程对象处于新建状态,此时已经有了相应的内存空间和资源
    2 线程创建之后就具备了运行的条件,一旦轮到它来享用cpu资源时,就可以脱离创建它的主线程,独立开始自己的生命周期了
    3  一个正在被执行的线程可能被人为的中断,让出cpu的使用权,暂时终止自己的执行,进入阻塞状态,阻塞时他不能进入排队序列,只有当引起阻塞的原因被清除时,线程才可以转入就绪态,重新进入到线程队列中排队等待cpu资源,以便从原来终止处继续执行
    4 处于死亡状态的线程不具备继续运行的能力,线程死亡的原因有二,一个是正常运行的线程完成了它的全部工作,另一个是线程被提前强制性终止,所谓的死亡状态就是释放了实体,即释放了分配你线程对象的内存

评分

参与人数 1技术分 +1 收起 理由
枫儿 + 1 赞一个!

查看全部评分

回复 使用道具 举报
左拉 中级黑马 2014-4-18 15:09:12
9#
public Thread(Runnable target)
通过Thread的构造方法可以发现:实现Runnable接口的线程也是通过Thread类调用start()方法来双启动线程的,接收Runnable接口的子类实例,然后通过Thread启动线程,这其实是一种代理设计模式。
                th1.start();   //这个地方明明是th1调用的start方法,为什么上面的this却是Threst
                th2.start();
这两句代码在main方法中,main方法是静态方法,直接通过类名启动main线程,在静态方法中怎么可以使用关键字this.
而在run()方法中,本类已经继承了Thread类,所以也是子线程,又非静态方法,所以可以用this,表示当前对象(当前的子线程)
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马