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

          常用鏈接

          留言簿(2)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          51CTO

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜


                  Java線程類有兩種實現(xiàn)方式,第一種就是繼承Thread類,另一種是現(xiàn)實Runnable接口。這兩種實現(xiàn)方式的區(qū)別很大,下面就說一下它們之間到底有什么區(qū)別。

          我們首先用第一種方式寫一個線程類:
          代碼如下:


          package Ticket;


          public class Extends {
           
           public static void main(String[] args){
                    //實例化進(jìn)程并準(zhǔn)備執(zhí)行
                    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(){
               
                    //這里之所以要循環(huán)300次,就是為了讓所有的 車票都賣出去!可能你會想,為什么不是30呢?
                    //嘿嘿。。。聰明的你肯定明白這個循環(huán)的次數(shù)為什么會多出票數(shù)很多?=====其實我開始也不知道?。?!  ==||| 
                  
                    for(int i=0;i<300;i++){
                         try {
                              //調(diào)用sell()方法
                              this.sell();
                              Thread.sleep(10);
                           } catch (InterruptedException e) {
                                      e.printStackTrace();
                           }
            }
           
           }
                     public void sell(){
                            if(ticket>0){
                                     System.out.println(Thread.currentThread().getName() + " ===> 還剩下" + (ticket--) + "車票");
                            }
           }
          }



          看看這個程序的運行結(jié)果你就明白為什么繼承Thread類實現(xiàn)線程類的一個弊端 




          ------------------------------------------------
          大家都發(fā)現(xiàn)了吧!輸出的結(jié)果和預(yù)想的不一樣?。?!

          我們來分析一下代碼,查看main函數(shù):
                    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,但賦值了三次?。。∫簿褪乾F(xiàn)在有三個ticket!!!
          這樣并不能實現(xiàn)資源共享!
          我們知道我們利用多線程就是為了將多個線程去處理一個數(shù)據(jù)的集合?。。?他們是同時處理的?。?!如果向上面的話,并沒有將數(shù)據(jù)的集合(ticket)進(jìn)行共享,而是將每一個類都從新建了一個數(shù)據(jù)的集合,分別對自己的集合進(jìn)行處理!?。?!
          如果想解決這個問題,其實也很簡單,不過如果當(dāng)數(shù)據(jù)的類型和種類比較多的時候,這樣寫就太麻煩了?。。。?br />
          那實現(xiàn)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--) + "車票");
                  }
                 
              } 
          }
                 

          ---------------------------------------------
          這段程序的運行結(jié)果:


          看看這個結(jié)果是不是和自己想的一樣啊?。?!這樣就可以了?。?!用這個方法去創(chuàng)建一個線程類是不是可以達(dá)到資源共享?。。?!
          其實??!我看來,所謂的資源共享也就是將一個數(shù)據(jù)的集合讓多個線程去處理?。?!
          我們看一下代碼?。?!
                  MyThread01 mt = new MyThread01();
                  new Thread(mt,"001窗口").start();
                  new Thread(mt,"002窗口").start();
                  new Thread(mt,"003窗口").start();

          我們可以看出這個過程中,我們只聲明并實例化了一個MyThread01類,也就是說在這里過程中,給ticket進(jìn)行了初始化?。?!
          但大家要注意的是:真正創(chuàng)建處理數(shù)據(jù)的線程是
                  new Thread(mt,"001窗口").start();
                  new Thread(mt,"002窗口").start();
                  new Thread(mt,"003窗口").start();
          因此,這樣可以將一個ticket的數(shù)據(jù)集 由三個線程來處理?。。?br /> 這樣就是所謂的資源共享?。?!
          ok???



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


          總結(jié)一下這兩種方式的特點:

          1.繼承Thread來創(chuàng)建線程類的方法,在繼承了Thread后,不能再繼承其他類,這樣靈活性就不如實現(xiàn)Runnable接口來創(chuàng)建線程類的方法了!??!
          2.正如上面所說的使用實現(xiàn)Runnable接口來創(chuàng)建線程類的方法可以達(dá)到資源共享?。。。ㄔ谶@里說明一下:繼承Thread類來創(chuàng)建線程類的方法也可以實現(xiàn)資源共享,只不過比較麻煩!!!因此,在創(chuàng)建線程類的時候,應(yīng)優(yōu)先選擇實現(xiàn)Runnable接口來創(chuàng)建線程類的方法!?。。?br />






          posted on 2010-11-07 20:30 tovep 閱讀(5968) 評論(8)  編輯  收藏

          FeedBack:
          # re: Java_線程類兩種創(chuàng)建方式的區(qū)別[未登錄] 2010-11-07 22:15 feenn
          ............
          第一種實現(xiàn)方法中,每一個thread都傳入了一個new MyThread(),那是三個實例啊,能和runnable的實現(xiàn)一樣的么,能實現(xiàn)共享才怪了。。。。  回復(fù)  更多評論
            
          # re: Java_線程類兩種創(chuàng)建方式的區(qū)別 2010-11-07 23:14 Tovep
          @feenn
          其實實現(xiàn)有很多方法啊!
          你可以把ticket設(shè)置為static就可以了?。?!  回復(fù)  更多評論
            
          # re: Java_線程類兩種創(chuàng)建方式的區(qū)別[未登錄] 2010-11-08 08:45 feenn
          @Tovep
          是可以有很多方法,但是你文中的這種比較方法明顯是有問題的。繼承Thread的方法在實例化的時候使用了三個實例,而在實現(xiàn)Runnable的時候?qū)嵗皇褂昧艘粋€實例,因此這兩種實驗是不具備可比性的,因此結(jié)論也無從說起。  回復(fù)  更多評論
            
          # re: Java_線程類兩種創(chuàng)建方式的區(qū)別[未登錄] 2010-11-08 08:54 feenn
          @Tovep
          因此針對于你的文章,結(jié)論1是正確的,但是文章的例子和整個推導(dǎo)過程并不能體現(xiàn)這個結(jié)論。
          對于結(jié)論2,個人不敢茍同,是否方便實現(xiàn)共享是設(shè)計的問題,而不是某個類或接口天生具有的屬性。因此,能方便的實現(xiàn)資源共享并不是我們在設(shè)計的時候優(yōu)先選擇runnable的理由。  回復(fù)  更多評論
            
          # re: Java_線程類兩種創(chuàng)建方式的區(qū)別 2010-11-08 17:27 weyling
          恩,你懂的@feenn
            回復(fù)  更多評論
            
          # re: Java_線程類兩種創(chuàng)建方式的區(qū)別 2010-11-17 09:49 icejoywoo
          你第一個例子程序中每次運行開始都new了一個線程, 如果和第二個例子一樣, 只寫一個new, 然后start三次的話, 結(jié)果是一樣的, 只是線程的執(zhí)行順序是隨機的  回復(fù)  更多評論
            
          # re: Java_線程類兩種創(chuàng)建方式的區(qū)別[未登錄] 2014-12-23 09:54 dd
          # re: Java_線程類兩種創(chuàng)建方式的區(qū)別 2015-05-22 10:57 www
          用個靜態(tài)變量就ok了,還要搞得這么麻煩  回復(fù)  更多評論
            

          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          主頁 主站蜘蛛池模板: 漯河市| 桦甸市| 辛集市| 怀柔区| 沁水县| 承德县| 英吉沙县| 科技| 莆田市| 宁河县| 宜兴市| 北海市| 安康市| 玛沁县| 佳木斯市| 石阡县| 贡觉县| 南宫市| 丰台区| 宜川县| 砚山县| 台北市| 共和县| 勐海县| 鹤壁市| 沂源县| 延庆县| 和平县| 庄河市| 石首市| 盐城市| 北川| 夹江县| 友谊县| 银川市| 肇州县| 嘉峪关市| 遂宁市| 镇宁| 巴马| 陵水|