随笔 - 20  文章 - 57  trackbacks - 0
<2015年5月>
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456

常用链接

留言簿(2)

随笔分类

随笔档案

文章分类

文章档案

51CTO

搜索

  •  

最新评论

阅读排行榜

评论排行榜


        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接口来创建线程类的方法!!!)







posted on 2010-11-07 20:30 tovep 阅读(5944) 评论(8)  编辑  收藏

FeedBack:
# re: Java_线程类两种创建方式的区别[未登录] 2010-11-07 22:15 feenn
............
第一种实现方法中,每一个thread都传入了一个new MyThread(),那是三个实例啊,能和runnable的实现一样的么,能实现共享才怪了。。。。  回复  更多评论
  
# re: Java_线程类两种创建方式的区别 2010-11-07 23:14 Tovep
@feenn
其实实现有很多方法啊!
你可以把ticket设置为static就可以了!!!  回复  更多评论
  
# re: Java_线程类两种创建方式的区别[未登录] 2010-11-08 08:45 feenn
@Tovep
是可以有很多方法,但是你文中的这种比较方法明显是有问题的。继承Thread的方法在实例化的时候使用了三个实例,而在实现Runnable的时候实例化只使用了一个实例,因此这两种实验是不具备可比性的,因此结论也无从说起。  回复  更多评论
  
# re: Java_线程类两种创建方式的区别[未登录] 2010-11-08 08:54 feenn
@Tovep
因此针对于你的文章,结论1是正确的,但是文章的例子和整个推导过程并不能体现这个结论。
对于结论2,个人不敢苟同,是否方便实现共享是设计的问题,而不是某个类或接口天生具有的属性。因此,能方便的实现资源共享并不是我们在设计的时候优先选择runnable的理由。  回复  更多评论
  
# re: Java_线程类两种创建方式的区别 2010-11-08 17:27 weyling
恩,你懂的@feenn
  回复  更多评论
  
# re: Java_线程类两种创建方式的区别 2010-11-17 09:49 icejoywoo
你第一个例子程序中每次运行开始都new了一个线程, 如果和第二个例子一样, 只写一个new, 然后start三次的话, 结果是一样的, 只是线程的执行顺序是随机的  回复  更多评论
  
# re: Java_线程类两种创建方式的区别[未登录] 2014-12-23 09:54 dd
SB  回复  更多评论
  
# re: Java_线程类两种创建方式的区别 2015-05-22 10:57 www
用个静态变量就ok了,还要搞得这么麻烦  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航:
博客园   IT新闻   Chat2DB   C++博客   博问  
 
主页