Java_线程类两种创建方式的区别

转自http://www.blogjava.net/tovep/archive/2010/11/07/337479.html

 Java线程类有两种实现方式,第一种就是继承Thread类,另一种是现实Runnable接口。这两种实现方式的区别很大,下面就说一下它们之间到底有什么区别。

我们首先用第一种方式写一个线程类:
代码如下:


package Ticket;


public class Extends {
 
 public static void main(String[] args){
          //实例化进程并准备执行
          new Thread(new MyThread(),"001窗口").start();
          new Thread(new MyThread(),"001窗口").start();
          new Thread(new MyThread(),"001窗口").start();
 
         }

}

class MyThread extends Thread{
         //定义一个变量
          private int ticket = 10;
 
          public void run(){
     
          //这里之所以要循环300次,就是为了让所有的 车票都卖出去!可能你会想,为什么不是30呢?
          //嘿嘿。。。聪明的你肯定明白这个循环的次数为什么会多出票数很多?=====其实我开始也不知道!!!  ==||| 
        
          for(int i=0;i<300;i++){
               try {
                    //调用sell()方法
                    this.sell();
                    Thread.sleep(10);
                 } catch (InterruptedException e) {
                            e.printStackTrace();
                 }
  }
 
 }
           public void sell(){
                  if(ticket>0){
                           System.out.println(Thread.currentThread().getName() + " ===> 还剩下" + (ticket--) + "车票");
                  }
 }
}



看看这个程序的运行结果你就明白为什么继承Thread类实现线程类的一个弊端 




------------------------------------------------
大家都发现了吧!输出的结果和预想的不一样!!!

我们来分析一下代码,查看main函数:
          new Thread(new MyThread(),"001窗口").start();
          new Thread(new MyThread(),"001窗口").start();
          new Thread(new MyThread(),"001窗口").start();

我们可以看出,实例化了三个MyThread类,这样的话,private int ticket = 10;就运行了三次,所以ticket打印出来的 也就是30张;在这里注意一下并不是ticket赋值为30,而是ticket赋值为10,但赋值了三次!!!也就是现在有三个ticket!!!
这样并不能实现资源共享!
我们知道我们利用多线程就是为了将多个线程去处理一个数据的集合!!! 他们是同时处理的!!!如果向上面的话,并没有将数据的集合(ticket)进行共享,而是将每一个类都从新建了一个数据的集合,分别对自己的集合进行处理!!!!
如果想解决这个问题,其实也很简单,不过如果当数据的类型和种类比较多的时候,这样写就太麻烦了!!!!

那实现Runnable接口的线程类可不可以呢!!???

下面来看一看:

代码如下:


package IO;

public class Inter {

    public static void main(String[] args){
        //声明并实例化一个MyThread01类
        MyThread01 mt = new MyThread01();
        new Thread(mt,"001窗口").start();
        new Thread(mt,"002窗口").start();
        new Thread(mt,"003窗口").start();

    }
   
}

class MyThread01 implements Runnable{
   
    private int ticket = 10;   
    public void run(){   
        for(int i=0;i<200;i++){
            try {
                this.sell();
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
       
    }
    public void sell(){
        if(ticket>0){
            System.out.println(Thread.currentThread().getName() + " ===> 还剩下" + (ticket--) + "车票");
        }
       
    } 
}
       

---------------------------------------------
这段程序的运行结果:


看看这个结果是不是和自己想的一样啊!!!这样就可以了!!!用这个方法去创建一个线程类是不是可以达到资源共享啊!!!
其实啊!我看来,所谓的资源共享也就是将一个数据的集合让多个线程去处理!!!
我们看一下代码!!!
        MyThread01 mt = new MyThread01();
        new Thread(mt,"001窗口").start();
        new Thread(mt,"002窗口").start();
        new Thread(mt,"003窗口").start();

我们可以看出这个过程中,我们只声明并实例化了一个MyThread01类,也就是说在这里过程中,给ticket进行了初始化!!!
但大家要注意的是:真正创建处理数据的线程是
        new Thread(mt,"001窗口").start();
        new Thread(mt,"002窗口").start();
        new Thread(mt,"003窗口").start();
因此,这样可以将一个ticket的数据集 由三个线程来处理!!!
这样就是所谓的资源共享!!!
ok???



=====================================================================


总结一下这两种方式的特点:

1.继承Thread来创建线程类的方法,在继承了Thread后,不能再继承其他类,这样灵活性就不如实现Runnable接口来创建线程类的方法了!!!
2.正如上面所说的使用实现Runnable接口来创建线程类的方法可以达到资源共享!!!(在这里说明一下:继承Thread类来创建线程类的方法也可以实现资源共享,只不过比较麻烦!!!因此,在创建线程类的时候,应优先选择实现Runnable接口来创建线程类的方法!!!)

 

你可能感兴趣的:(java,多线程,thread,.net)