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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 燕国庆 高级黑马   /  2012-10-25 11:36  /  1368 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文


class ticket implements Runnable
{
private int tick=100;
public void run()
{
  while(true)
  {
   if(tick>0)
   {
    System.out.println(Thread.currentThread().getName()+"sale---"+tick--);
   }
  }
}
}

class  TicketDemo
{
public static void main(String[] args)
{
  ticket t=new ticket();     //此处创建了一个ticket类的对象
  Thread t1=new Thread(t);  //此处相当于Runnable R=t   (多态)   在这个地方Thread t1=new Thread(t); 到底做了哪些事?t1是如何通过Thread(Runnable R)构造函数指向t的对象,从而
  Thread t2=new Thread(t);                                                                                                                         调用t 的run方法的?
  Thread t3=new Thread(t);
  Thread t4=new Thread(t);
  t1.start();
  t2.start();
  t3.start();
  t4.start();
}
}
求帮助,这个地方搞得我有点晕,谁能帮我解释一下!!!谢谢!!!!

评分

参与人数 1技术分 +1 收起 理由
唐志兵 + 1 赞一个!

查看全部评分

5 个回复

倒序浏览
Thread t1=new Thread(t);  一初始化就创建了一个线程,然后通过实例t和线程关联起来,接着通过线程的start方法开启线程,start一开启,就会执行run中存放的代码,也就是线程运行的代码,我的理解是这样。

评分

参与人数 1技术分 +1 收起 理由
唐志兵 + 1 赞一个!

查看全部评分

回复 使用道具 举报
本帖最后由 翁鹏 于 2012-10-25 12:19 编辑

实现Runnable接口的类只是线程要执行的一个任务,Runnable不是线程。而我们必须把要执行的任务交给线程去执行,Thread类才是线程类,我们把Runnable对象传递给Thread(线程)的构造函数,让线程可以执行里面的任务(run方法中的代码)。Thread类的start方法开启线程,并调用了Runnable对象中的run方法。start方法到底是怎么实现这两个功能的我没有研究过。

你可以去看看start()方法的源代码,start()方法开启线程用到了一个native本地方法。应该和系统有关吧。
  1. public synchronized void start() {
  2.         /**
  3.          * This method is not invoked for the main method thread or "system"
  4.          * group threads created/set up by the VM. Any new functionality added
  5.          * to this method in the future may have to also be added to the VM.
  6.          *
  7.          * A zero status value corresponds to state "NEW".
  8.          */
  9.         if (threadStatus != 0)
  10.             throw new IllegalThreadStateException();

  11.         /* Notify the group that this thread is about to be started
  12.          * so that it can be added to the group's list of threads
  13.          * and the group's unstarted count can be decremented. */
  14.         group.add(this);

  15.         boolean started = false;
  16.         try {
  17.             start0();
  18.             started = true;
  19.         } finally {
  20.             try {
  21.                 if (!started) {
  22.                     group.threadStartFailed(this);
  23.                 }
  24.             } catch (Throwable ignore) {
  25.                 /* do nothing. If start0 threw a Throwable then
  26.                   it will be passed up the call stack */
  27.             }
  28.         }
  29.     }

  30.     private native void start0();

  31.     /**
  32.      * If this thread was constructed using a separate
  33.      * <code>Runnable</code> run object, then that
  34.      * <code>Runnable</code> object's <code>run</code> method is called;
  35.      * otherwise, this method does nothing and returns.
  36.      * <p>
  37.      * Subclasses of <code>Thread</code> should override this method.
  38.      *
  39.      * @see     #start()
  40.      * @see     #stop()
  41.      * @see     #Thread(ThreadGroup, Runnable, String)
  42.      */
  43.     @Override
  44.     public void run() {
  45.         if (target != null) {
  46.             target.run();
  47.         }
  48.     }
复制代码

复制代码

评分

参与人数 1技术分 +1 收起 理由
唐志兵 + 1 赞一个!

查看全部评分

回复 使用道具 举报
翁鹏 发表于 2012-10-25 11:47
实现Runnable接口的类只是线程要执行的一个任务,Runnable不是线程。而我们必须把要执行的任务交给线程去执 ...

我们把Runnable对象传递给Thread(线程)的构造函数,                  这时问题就出现了,构造函数里面是如何实现让定义的线程引用指向具体的Runnable子类对象的
回复 使用道具 举报
燕国庆 发表于 2012-10-25 12:04
我们把Runnable对象传递给Thread(线程)的构造函数,                  这时问题就出现了,构造函数里面 ...

Thread t = new Thread(Runnable r);  这里t并没有指向Runnable子类对象啊,t对象包含了Runnable对象啊。
has-a关系啊,组合关系啊。t调用start()开启线程,在再start里面调用传递给你的Runnable对象中的run方法就行了。
回复 使用道具 举报
本帖最后由 廖智 于 2012-10-25 12:26 编辑

class ticket implements Runnable
{
private int tick=100;
public void run()
{
  while(true)
  {
   if(tick>0)
   {
    System.out.println(Thread.currentThread().getName()+"sale---"+tick--);
   }
  }
}
}

class  TicketDemo
{
public static void main(String[] args)
{
  ticket t=new ticket();     //此处创建了一个ticket类的对象
  Thread t1=new Thread(t);  这里你可以简单理解Thread t1 = new Thread(t);所做的事就是让ticket这个对象和线程对象有关联,这样ticket对象中的run才能被线程相应的线程去执行。如果没有关联run方法也就相当于一个普通的方法,不会被线程对象Thread执行。
  Thread t2=new Thread(t);                                                                                                                        
  Thread t3=new Thread(t);
  Thread t4=new Thread(t);
  t1.start();
  t2.start();
  t3.start();
  t4.start();
}
}

评分

参与人数 1技术分 +1 收起 理由
唐志兵 + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马