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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 王红霞 中级黑马   /  2012-6-15 21:59  /  2042 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 王红霞 于 2012-7-8 23:51 编辑

        学习线程的时候老是分不清run和start的关系,二者貌似run和start都能启动线程。今天查了很多资料,终于搞清楚了二者的区别,于是记录下来与大家分享:

       区别:调用start方法实现多线程,而调用run方法没有实现多线程
Start:
      用start方法来启动线程,真正实现了多线程运行,这时无需等待run方法体代码执行完毕而直接继续执行下面的代码。通过调用Thread类的start()方法来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,一旦得到spu时间片,就开始执行run()方法,这里方法run()称为线程体,它包含了要执行的这个线程的内容,Run方法运行结束,此线程随即终止。
Run:
     run()方法只是类的一个普通方法而已,如果直接调用Run方法,程序中依然只有主线程这一个线程,其程序执行路径还是只有一条,还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码,这样就没有达到写线程的目的。
总结:调用start方法方可启动线程,而run方法只是thread的一个普通方法调用,还是在主线程里执行。

3 个回复

倒序浏览
先顶一下,弄个例子来对比下能更好的分清他们的区别,不对的地方请高手之处哈!
class NewThread implements Runnable {
Thread t;
public NewThread() {
t = new Thread(this,"Demo thread");
System.out.println("Child thread : " + t);
t.run();
}
public void run(){
try{
for( int i = 5; i > 0; i --){
System.out.println("Child thread :" + i);
Thread.sleep(500);
}

}catch(InterruptedException e){
System.out.println("Child interrupted.");
}
System.out.println("Exiting child thread.");

}
}

public class TestDemo{
public static void main(String args[]){
new NewThread();
try{
for( int i = 5; i > 0; i --){
System.out.println("Main thread :" + i);
Thread.sleep(1000);
}
}catch(InterruptedException e){
System.out.println("Main interrupted.");
}
System.out.println("Exiting Main thread.");
}
}

这是一个实现多线程的程序,运行结果如下:
Child thread : Thread[Demo thread,5,main]
Main thread :5
Child thread :5
Child thread :4
Main thread :4
Child thread :3
Child thread :2
Main thread :3
Child thread :1
Exiting child thread.
Main thread :2
Main thread :1
Exiting Main thread.

这里,把 start()改成run()后会出现的结果是:
修改之后运行结果:
Child thread : Thread[Demo thread,5,main]
Child thread :5
Child thread :4
Child thread :3
Child thread :2
Child thread :1
Exiting child thread.
Main thread :5
Main thread :4
Main thread :3
Main thread :2
Main thread :1
Exiting Main thread.
是不是很清晰了,程序运行成为了单线程顺序执行。这是因为 start方法:用来启动一个线程, 这时此线程是处于就绪状态, 并没有运行。 然后通过此Thread类调用方法run()来完成其运行操作的, 这里方法run()称为线程体, 它包含了要执行的这个线程的内容, run方法运行结束, 此线程终止, 而CPU再运行其它线程, 直接用run方法: 这只是调用一个方法而已, 程序中依然只有主线程--这一个线程, 其程序执行路径还是只有一条, 这样就没有达到写线程的目的。 总之,线程就是为了更好地利用CPU,提高程序运行速率的!不信就执行一下哦。

评分

参与人数 1技术分 +1 收起 理由
黄奕豪 + 1 赞一个!

查看全部评分

回复 使用道具 举报
之所以出现线程,就是为了更好的利用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);
  }
}
}

评分

参与人数 1技术分 +1 收起 理由
黄奕豪 + 1 赞一个!

查看全部评分

回复 使用道具 举报
      由于Thread类用于描述线程,该类就定义了一个功能,用于存储线程要运行的代码,这个方法就是run()方法。也就是说,Thread中的run()方法是用于封装线程要运行的代码。
    在创建多线程对象后,如果是直接调用对象中的run()方法,则该run()方法的调用和普通的对象调用没有什么区别,此时,并没有开启新的线程,属于单线程。也就是说,run()方法此时是在主线程中运行的。而线程对象调用start()方法,则启动了新线程,并且start()方法会自动调用run()方法,此时,run()方法中的代码就被新的线程执行了。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马