浅谈Java多线程之Threa类和Runnable接口的区别

来源:互联网 发布:手机网络机顶盒遥控器 编辑:程序博客网 时间:2024/06/05 10:51

众所周知Java多线程通过两种方式创建:一种是继承Thread类,另一种是实现Runnable接口。那么,两种方式有什么区别?哪种方式更好些?  

Thread类定义在Java.lang包中,只要继承Thread类同时覆写本类的run()方法就能操作多线程,但一个类只能继承一个父类,这是继承Thread类的局限。

Thread类示例:

class Test extends Thread{  private String name;  public Test(String name){  super();this.name = name;}  public void run(){  for(int i=0;i<10;i++){  System.out.println("线程启动:"+this.name+",i="+i);  }  }  }   public class ThreadTest{  public static void main(String[] args){  Test t1=new Test("线程A");  Test t2=new Test("线程B");  t1.run();  t2.run();  }  }

结果很有规律,第一个对象先执行,然第二个对象再执行,并没有相互交替运行,说明线程没启用,只是普通的方法调用。查看JDK文档发现一旦调用start()方法,则通过JVM找到run()方法启动线程。

public class ThreadTest{  public static void main(String[] args){  Test t1=new Test("线程A");  Test t2=new Test("线程B");  t1.start();  t2.start();  }  }

这样程序能正常完成交互式运行,为什么非要使用start()方法启动多线程?

在JDK安装目录下,src.zip是Java源程序,通过此找到Thread类的start()方法的定义,发现使用private native void start();其中native关键字表示允许调用操作系统的底层函数,这样的技术称为JNI技术(Java Native Interface)。

Runnabl接口示例:

实际开发中多线程操作较少使用Thread类,主要通过Runnable接口完成。

class Test implements Runnable{  private String name;  public Test(String name){  this.name = name;}  public void run(){  for(int i=0;i<10;i++){  System.out.println("线程启动:"+this.name+",i="+i);  }  }  }   public class RunnableTest{  public static void main(String[] args){  Test t1 = new Test("线程1");Test t2 = new Test("线程2");new Thread(t1).start();new Thread(t2).start();}  }

使用Runnable接口定义的子类没有start()方法,只有Thread类中才有。通过JDK文档查看Thread类有一构造方法:Public Thread(Runnable targer)接受Runnable的子类实例,也就是说通过Thread类启动start()方法实现Runnable的多线程。

两种实现方式的区别和联系:

程序开发中多线程永远以实现Runnable接口为主,因为和继承Thread类相比有如下好处:

1、避免单继承的局限,Java中一个类允许实现多个接口;

2、适合于资源的共享。

Thread类卖票程序:

class Ticket extends Thread{private int tick=10;public void run(){while(true){if(tick>0)System.out.println(Thread.currentThread().getName()+"...SaleTikcet...."+tick--);}}}class TicketDemo{public static void main(String[] args){Ticket t1 = new Ticket();Ticket t2 = new Ticket();Ticket t3 = new Ticket();t1.start();//每个线程都各卖10张,共计30张票,t2.start();//实际只有10张票,每个线程都各卖各的,t3.start();//没有达到资源共享目的。}}
如果用Runnable接口就能实现资源共享,示例如下:

class Ticket implements Runnable{private int tick = 10;public void run(){while(true){if(tick>0){System.out.println(Thread.currentThread().getName()+"...SaleTicket..."+tick--);}}}}class TicketDemo2{public static void main(String[] args){Ticket t = new Ticket();new Thread(t).start();//同一t,在Thread类中不可以,new Thread(t).start();//如果同一个实例化对象,会报异常。new Thread(t).start();}}
现在程序中有三个线程,但一共只卖了10张票,达到了资源共享目的。

通过查看JDK文档发现:public class Thread extends Object implements Runnable ,说明Thread类也是Runnable接口的子类。 


PS:初碰Java,网上搜索到许多这样的文章;口语化严重,措辞生硬晦涩,忍不住想整改。借用模板重新编写,原作者不详,看到请告之。

 

 

 

 

 

 

 

原创粉丝点击