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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 崔云飞 于 2012-6-22 09:59 编辑

为什么需要 run ()和 start ()方法,我们可以只用 run ()方法来完成任务,干嘛还要弄一个start出来,那么run和start有什么区别呢?

9 个回复

倒序浏览
本帖最后由 黑马—陈磊 于 2012-6-21 20:30 编辑

我们需要 run ()和start ()这两个方法是因为 JVM 创建一个单独的线程不同于普通方法的调用,所以这项工作由线程的 start 方法来完成,start 由本地方法实现,需要显示地被调用,使用这俩个方法的另外一个好处是任何一个对象都可以作为线程运行,只要实现了 Runnable 接口,这就避免因继承了 Thread 类而造成的 Java 的多继承问题。这个像一道面试题,看过的。

回复 使用道具 举报
run():在本线程内调用该Runnable对象的run()方法,可以重复多次调用;
start():启动一个线程,调用该Runnable对象的run()方法,不能多次启动一个线程;
回复 使用道具 举报
1.start()方法来启动线程,真正实现了多线程运行,这时无需等待run方法体代码执行完毕而直接继续执行下面的代码:

通过调用Thread类的start()方法来启动一个线程,
这时此线程是处于就绪状态,
并没有运行。
然后通过此Thread类调用方法run()来完成其运行操作的,
这里方法run()称为线程体,
它包含了要执行的这个线程的内容,
Run方法运行结束,
此线程终止,
而CPU再运行其它线程,



2.run()方法当作普通方法的方式调用,程序还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码:

而如果直接用Run方法,
这只是调用一个方法而已,
程序中依然只有主线程--这一个线程,
其程序执行路径还是只有一条,
这样就没有达到写线程的目的。

回复 使用道具 举报
本帖最后由 孙胜录 于 2012-6-21 20:52 编辑

start()是在主线程外开始运行一个新的线程,run()的就在主线里执行线程的run方法说白了就是主线程直接执行了这个线程。
API中时这样解释的:
public void start()使该线程开始执行;Java 虚拟机调用该线程的 run 方法。
结果是两个线程并发地运行;当前线程(从调用返回给 start 方法)和另一个线程(执行其 run 方法)。
不要使用Thread类的run()方法,它不会创建新的线程。
回复 使用道具 举报
之所以出现线程,就是为了更好的利用CPU,让她更加“精明”的干活。

通过调用Thread类的start()方法来启动一个线程,
这时此线程是处于就绪状态,
并没有运行。
然后通过此Thread类调用方法run()来完成其运行操作的,
这里方法run()称为线程体,
它包含了要执行的这个线程的内容,
Run方法运行结束,
此线程终止,
而CPU再运行其它线程,

而如果直接用Run方法,
这只是调用一个方法而已,
程序中依然只有主线程--这一个线程,
其程序执行路径还是只有一条,
这样就没有达到写线程的目的。

记住:线程就是为了更好地利用CPU,
提高程序运行速率的!

public class TestThread1{
public static void main(String[] args){
  Runner1 r=new Runner1();
  //r.run();//这是方法调用,而不是开启一个线程
  Thread t=new Thread(r);//调用了Thread(Runnable target)方法。且父类对象变量指向子类对象。
  t.start();
  
  for(int i=0;i<100;i++){
   System.out.println("进入Main Thread运行状态");
   System.out.println(i);
  }
}
}
class Runner1 implements Runnable{ //实现了这个接口,jdk就知道这个类是一个线程
public void run(){
  
  for(int i=0;i<100;i++){
   System.out.println("进入Runner1运行状态");
   System.out.println(i);
  }
}
}
回复 使用道具 举报
本帖最后由 逝去的记忆ヽ 于 2012-6-21 21:05 编辑

Start:
      用start方法来启动线程,真正实现了多线程运行,这时无需等待run方法体代码执行完毕而直接继续执行下面的代码。通过调用Thread类的start()方法来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,一旦得到spu时间片,就开始执行run()方法,这里方法run()称为线程体,它包含了要执行的这个线程的内容,Run方法运行结束,此线程随即终止。
Run:
     run()方法只是类的一个普通方法而已,如果直接调用Run方法,程序中依然只有主线程这一个线程,其程序执行路径还是只有一条,还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码,这样就没有达到写线程的目的。
总结:调用start方法方可启动线程,而run方法只是thread的一个普通方法调用,还是在主线程里执行。
回复 使用道具 举报
Thread对象的run()方法在一种循环下,使线程一直运行,直到不满足条件为止,在你的main()里创建并运行了一些线程,调用Thread类的start()方法将为线程执行特殊的初始化的过程,来配置线程,然后由线程执行机制调用run()。如果你不调用start()线程就不会启动。





因为线程调度机制的行为是不确定的,所以每次运行该程序都会有不同的结果,你可以把你的循环次数增多些,然后看看执行的结果,你会发现main()的线程和Thread1是交替运行的。
4.还有就是尽管线程的调度顺序是不固定的,但是如果有很多线程被阻塞等待运行,调度程序将会让优先级高的线程先执行,而优先级低的线程执行的频率会低一些。





线程的启动是比较复杂的,需要为线程分配资源,它的START方法被调用时系统才会为线程分配资源。
你上面调用线程的run方法只能算普通的方法调用一样,得运行完run里面的代码整个程序才能往下进行,而如果调用start方法,线程和MAIN方法就会抢资源,打印的语句会交替出现,你把线程里的循环次数加到300,试一下依次调run、start和两次都调start方法时所出现的情况应该能看出点端倪~~~
回复 使用道具 举报
刘笑 中级黑马 2012-6-21 22:40:34
9#
例子:

public class Test {
public static void main(String[] args) {
  Runner runner = new Runner();
  Thread t = new Thread(runner);
  t.start();       //调用start()方法来启动线程s

runner.run();    //直接通过类调用类中的方法来启动线程
}

}
class Runner implements Runnable {
public void run() {
  for(int i=0;i<10;i++){
   System.out.println("i = "+i);
  }
}
}

在启动线程时候,有两种方法可以使用

start()为一半通用的启动线程的方法,通过调用线程类Thread的start()方法来启动线程,然后线程Thread类通过调用run()方法来实现线程的操作,而其中的run()方法中的内容实为线程体,即为该线程所要执行的内容。run()方法执行结束,该线程也就终止了,cpu在执行其他的线程

如果将线程看做一般的Java类的话,则run()方法相当于普通的方法调用,通过普通的java类实例.run()来启动线程,即执行该方法体的内容。最终程序执行的只有主线程这一个。

回复 使用道具 举报
这两个方法都是Thread类和Runnable接口中的函数。
通过调用Thread类或Runnable接口的start()方法来启动一个线程,这时此线程是处于就绪状态,并没有运行,然后通过此调用方法run()来完成其运行操作的,这里方法run()称为线程体,它包含了要执行的这个线程的内容,Run方法运行结束,此线程终止,而CPU再运行其它线程。 而如果直接调用Run方法,这只是调用一个方法而已,程序中依然只有主线程--这一个线程,其程序执行路径还是只有一条,这样就没有达到写线程的目的。
所以需要多线程,则调用start()方法。如果直接调用run()方法,则不能实现多线程效果,只是普通的函数调用而已。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马