黑马程序员技术交流社区

标题: 一道多线程小题求各位大仙解释。 [打印本页]

作者: 王少雷    时间: 2012-12-31 14:39
标题: 一道多线程小题求各位大仙解释。
package com.thread;

public class MyRunnable implements Runnable{

public void run() {
System.out.println("MyThread:run()");
}
public void start() {
System.out.println("MyThread:start()");
}

}


package com.thread;

public class MyThread extends Thread{
public void run() {
System.out.println("MyThread:run()");
}
public void start() {
System.out.println("MyThread:start()");
}

}


public static void main(String[] args) {

MyThread myThread = new MyThread();
MyRunnable myRunnable = new MyRunnable();
Thread thread = new Thread(myRunnable);
myThread.start();
thread.start();
}
结果?大概 概述。
作者: hanyahui    时间: 2012-12-31 14:55
MyThread中打印MyThread:start(),MyRunnable中打印 MyThread:run()
runnable中start是运行重写的run方法
作者: 嘿嘿小学徒    时间: 2012-12-31 15:01
本帖最后由 高一航 于 2012-12-31 15:06 编辑

结果是:
MyThread:start()
MyThread:run()
我给你添加了注释,比较好理解:
  1. class MyRunnable implements Runnable { //MyRunnable类实现了Runnable接口,因此可以使用多线程技术
  2.     /**
  3.      * @param 黑马程序员
  4.      * @author 高一航
  5.      */
  6.     public void run() {  //实现Runnable接口的类 必须复写run方法
  7.         System.out.println("MyThread:run()");
  8.     }

  9.     public void start() {
  10.         System.out.println("MyThread:start()");
  11.     }

  12. }

  13. public class TinyTest extends Thread {  //测试类集成了Thread类 , 因此也可以使用多线程
  14.     public void run() {
  15.         System.out.println("MyThread:run()");
  16.     }

  17.     public void start() {
  18.         System.out.println("MyThread:start()");
  19.     }

  20.     public static void main(String[] args) {

  21.         TinyTest myThread = new TinyTest();
  22.         MyRunnable myRunnable = new MyRunnable();
  23.         Thread thread = new Thread(myRunnable);
  24.         myThread.start(); //调用了20行的start方法
  25.         thread.start();//Thread的start调用的是第五行的run方法
  26.     }
  27. }
复制代码
你这是多线程的两种实现方式, 实现Runnable接口相对于继承Thread类来说,有如下显著的好处:

(1)适合多个相同程序代码的线程去处理同一资源的情况,把虚拟CPU(线程)同程序的代码,数据有效的分离,较好地体现了面向对象的设计思想。

(2)可以避免由于Java的单继承特性带来的局限。我们经常碰到这样一种情况,即当我们要将已经继承了某一个类的子类放入多线程中,由于一个类不能同时有两个父类,所以不能用继承Thread类的方式,那么,这个类就只能采用实现Runnable接口的方式了。

(3)有利于程序的健壮性,代码能够被多个线程共享,代码与数据是独立的。当多个线程的执行代码来自同一个类的实例时,即称它们共享相同的代码。多个线程操作相同的数据,与它们的代码无关。当共享访问相同的对象是,即它们共享相同的数据。当线程被构造时,需要的代码和数据通过一个对象作为构造函数实参传递进去,这个对象就是一个实现了Runnable接口的类的实例。
  1. ...end
复制代码

作者: 郑广昌    时间: 2012-12-31 15:07
运行结果是MyThread:start(),MyThread:run()

public static void main(String[] args) {

MyThread myThread = new MyThread();//创建MyThread对象
MyRunnable myRunnable = new MyRunnable();//创建MyRunnable对象
Thread thread = new Thread(myRunnable);//创建线程与MyRunnable对象相关联
myThread.start();//调用MyThread类中的start()方法
thread.start();//开启线程

作者: 范德农    时间: 2012-12-31 15:07
懒得打代码了,就着你的代码,逐条分析
package com.thread;

public class MyRunnable implements Runnable{

public void run() {
System.out.println("MyThread:run()");
}
//引用Runable接口的类自己定义的start()方法实际上对以改类实例做参数的线程毫无影响
public void start() {
System.out.println("MyThread:start()");
}

}


package com.thread;

public class MyThread extends Thread{
public void run() {
System.out.println("MyThread:run()");
}
//覆盖了本应继承自Thread类的start()方法,于是start()方法失去了启动线程的功能
public void start() {
System.out.println("MyThread:start()");
}

}
public static void main(String[] args) {
MyThread myThread = new MyThread();
MyRunnable myRunnable = new MyRunnable();
Thread thread = new Thread(myRunnable);
//控制台输出"MyThread:start()",因为你把Thread中的start()方法重写了,所以线程不会启动,自然不会运行run()方法
myThread.start();
//控制台输出"MyThread:run()",因为myRunnable的作用只是将它的run()方法内容传递给thread,它的start()方法对线程毫无影响
,实际调用的还是thread本身的start()方法
thread.start();
}
综上所述,实际只启动了两个线程,一个主线程,一个thread线程
作者: 范德农    时间: 2012-12-31 15:09
最终结果自然是:
MyThread:start()
MyThread:run()

作者: 王玮    时间: 2012-12-31 15:29
本帖最后由 高一航 于 2012-12-31 15:06 编辑


结果是:
MyThread:start()
MyThread:run()

MyThread myThread = new MyThread();
myThread.start();//调用myThread 的start方法。输出:MyThread:start()


MyRunnable myRunnable = new MyRunnable();
Thread thread = new Thread(myRunnable);
thread.start();  这是线程的第二种实现方式: 启动后,会执行myRunnable的 run方法,输出:MyThread:run()




作者: 何伟    时间: 2013-1-1 00:19

package com.thread;

public class MyRunnable implements Runnable{

public void run() {
System.out.println("MyThread1:run()");//打印的内容上下一样有点晕,我这里改下,这个是复写了接口的run方法,想要实现多线程这是必须的
}
public void start() {//这是myRunnable这个类自己的方法,runnable接口中并没有这个方法,用该类的实例对象可以调用它,
System.out.println("MyThread1:start()");
}

}


package com.thread;

public class MyThread extends Thread{
public void run() {
System.out.println("MyThread2:run()");
}
public void start() {//重写线程类的stsrt方法我还是第一次见,start方法是用来调用run方法的,你重写后就失去启动纯种的意义了
System.out.println("MyThread2:start()");
}

}


public static void main(String[] args) {

MyThread myThread = new MyThread();//创建myThrea对象
myThread.start();//mythrea调用的是MyThrea本类的start方法,打印的是MyThread2:start()


//这个是多线程
  MyRunnable myRunnable = new MyRunnable();// 创建任务对象
Thread thread = new Thread(myRunnable);// 创建线程对象,并把任务(myRunnable)给线程对象threa
thread.start();//打印的是MyThread1:run(),因为启动线程需要调用Thread类的start()方法。而start会去调用任务myRunnable的run方法
}


建议楼主使用实现接口的方式来完成多线程,因为java只支持单继承,一个类如果继承了Thread,那么就不能再去继承其他类了





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2