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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 杨扬 黑马帝   /  2011-12-23 13:40  /  4079 人查看  /  8 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 杨扬 于 2011-12-23 21:08 编辑

为什么启动线程用的是start(),却运行的是run()方法?

8 个回复

倒序浏览
关键字的意义不一样
回复 使用道具 举报
杨旭 黑马帝 2011-12-23 13:44:33
藤椅
执行start()方法  Java虚拟机 底层调用run()方法
回复 使用道具 举报
杨扬 黑马帝 2011-12-23 13:58:07
板凳
杨旭 发表于 2011-12-23 13:44
执行start()方法  Java虚拟机 底层调用run()方法

能否找到虚拟机是如何调用的呢.?
回复 使用道具 举报
杨旭 黑马帝 2011-12-23 14:05:21
报纸
  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.         group.add(this);
  12.         start0();
  13.         if (stopBeforeStart) {
  14.      stop0(throwableFromStop);
  15. }
  16.     }

  17.     private native void start0();
复制代码
上面是start()的源码  可以看到它调用了一个本地方法private native void start0();

native是方法修饰符。Native方法是由另外一种语言(如c/c++,FORTRAN,汇编)实现的本地方法。
因为在外部实现了方法,所以在java代码中,就不需要声明了,有点类似于接口。
回复 使用道具 举报
jdk文档:
使该线程开始执行;Java 虚拟机调用该线程的 run 方法。
结果是两个线程并发地运行;当前线程(从调用返回给 start 方法)和另一个线程(执行其 run 方法)。
多次启动一个线程是非法的。特别是当线程已经结束执行后,不能再重新启动。

源码:
public synchronized void start() {
        /**
  * This method is not invoked for the main method thread or "system"
  * group threads created/set up by the VM. Any new functionality added
  * to this method in the future may have to also be added to the VM.
  *
  * A zero status value corresponds to state "NEW".
         */
        if (threadStatus != 0)
            throw new IllegalThreadStateException();
        group.add(this);
        start0();
        if (stopBeforeStart) {
     stop0(throwableFromStop);
}
    }

    private native void start0();

发现没有,他调用了本地方法start0这个方法就是他底层实现的了,所以我们并看不到他显示的调用run方法,因为他是在底层调用的,虚拟机调用的,
native方法就是本地方法,是用其他语言写的,你自己也可以写native方法,就是JNI编程,想看到是看不到的。
回复 使用道具 举报
陈帅雷 黑马帝 2011-12-23 14:18:45
7#
启动一个线程是调用start()方法,使线程所代表的虚拟处理机处于可运行状态,这意味着它可以由JVM调度并执行。这并不意味着线程就会立即运行。run()方法可以产生必须退出的标志来停止一个线程。
回复 使用道具 举报
      一个线程的运行代码是放在run()方法中的,但创建一个线程有时候不一定马上执行吧,只有线程运行的时候才调用run()方法。
可是要能运行,首先的有执行的资格吧,那start()就是用来获取执行资格的,然后在适当的时候再调用run()方法执行线程具体的代码、
这也就是为什么启动线程要使用start()了,在运行时,start()又调用拥有具体代码的run()方法了
回复 使用道具 举报
于汝国 黑马帝 2011-12-23 16:55:57
9#
start()用来启动线程,这时无需等待run()方法体代码执行完毕而直接继续执行下面的代码:通过调用Thread类的start()方法此线程处于就需状态并没有运行,然后通过此Thread类调用方法run()来完成其运行操作的,这里方法run()称为线程体,她包含了要执行这个线程的内容,run方法运行结束,此线程终止。而cpu再运行其他线程。

run()当做普通的方法调用,程序还是要顺序执行,还是要等待run方法体执行完毕后才执行下面的代码,而如果直接用run方法,这只是调用一个方法而已,程序中依然只有主程序这一个线程,其程序执行路径还是一条,这样就没有达到写线程的目的。


举例说明:

public class TestThread(){

   public static void main(String []args){

        Runner1  r = new Runner1();

        //r.run();//这是方法调用,而不是开启一个线程
        Thread t = new Thread());//调用了Thread(Runnable target)方法。且父类对象变量指向子类对象。
        t.start();   

}
}

class  Runner1 implements Runnable{//实现了这个接口,jdk就知道这个类是一个线程

   public void run(){

     for(int j=0;j<100;j++){

          System.out.println("进入Runner1运行状态");

          System.out.println(j);

}
}
}

        for(int i=0;i<100;i++){

           System.out.println("进入了mianThread的运行方法");

            System.out.println(i);
}


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