posts - 7,  comments - 0,  trackbacks - 0
          <2010年2月>
          31123456
          78910111213
          14151617181920
          21222324252627
          28123456
          78910111213

          常用鏈接

          留言簿

          隨筆檔案

          文章檔案

          搜索

          •  

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          裝載:Mison(邁勝)http://bbs.misonsoft.com/thread-1225-1-2.html

          通過(guò)鐵路售票程序來(lái)理解實(shí)現(xiàn)多線程的兩種方法:通過(guò)java.lang.Thread類和通過(guò)Runnable接口
            java中有兩種實(shí)現(xiàn)多線程的方式。一是直接繼承Thread類,二是實(shí)現(xiàn)Runnable接口。那么這兩種實(shí)現(xiàn)多線程的方式在應(yīng)用上有什么區(qū)別呢?
            為了回答這個(gè)問(wèn)題,我們可以通過(guò)編寫(xiě)一段代碼來(lái)進(jìn)行分析。我們用代碼來(lái)模擬鐵路售票系統(tǒng),實(shí)現(xiàn)通過(guò)四個(gè)售票點(diǎn)發(fā)售某日某次列車的100張車票,一個(gè)售票點(diǎn)用一個(gè)線程表示。
            我們首先這樣編寫(xiě)這個(gè)程序:
           public class ThreadDome1
            
          public static void main(String[] args)
            ThreadTest t 
          = new ThreadTest(); 
            t.start(); 
            t.start(); 
            t.start(); 
            t.start(); 
            }
           
            }
           
            
          class ThreadTest extends Thread
            
          private int ticket = 100
            
          public void run()
            
          while(true)
            
          if(ticket > 0)
            System.out.println(Thread.currentThread().getName() 
          + 
            
          "is saling ticket" + ticket--); 
            }
          else
            
          break
            }
           
            }
           
            }
           
            }
          上面的代碼中,我們用ThreadTest類模擬售票處的售票過(guò)程,run方法中的每一次循環(huán)都將總票數(shù)減1,模擬賣出一張車票,同時(shí)該車票號(hào)打印出來(lái),直接剩余的票數(shù)到零為止。在ThreadDemo1類的main方法中,我們創(chuàng)建了一個(gè)線程對(duì)象,并重復(fù)啟動(dòng)四次,希望通過(guò)這種方式產(chǎn)生四個(gè)線程。從運(yùn)行的結(jié)果來(lái)看我們發(fā)現(xiàn)其實(shí)只有一個(gè)線程在運(yùn)行,這個(gè)結(jié)果告訴我們:一個(gè)線程對(duì)象只能啟動(dòng)一個(gè)線程,無(wú)論你調(diào)用多少遍start()方法,結(jié)果只有一個(gè)線程。
            我們接著修改ThreadDemo1,在main方法中創(chuàng)建四個(gè)Thread對(duì)象:
           public class ThreadDemo1
            
          public static void main(String[] args)
            
          new ThreadTest().start(); 
            
          new ThreadTest().start(); 
            
          new ThreadTest().start(); 
            
          new ThreadTest().start(); 
            }
           
            }
           
            
          class ThreadTest extends Thread
            
          private int ticket = 100
            
          public void run()
            
          while(true)
            
          if(ticket > 0)
            System.out.println(Thread.currentThread().getName() 
          + 
            
          " is saling ticket" + ticket--); 
            }
          else
            
          break
            }
           
            }
           
            }
           
            }

          這下達(dá)到目的了嗎?
            從結(jié)果上看每個(gè)票號(hào)都被打印了四次,即四個(gè)線程各自賣各自的100張票,而不去賣共同的100張票。這種情況是怎么造成的呢?我們需要的是,多個(gè)線程去處理同一個(gè)資源,一個(gè)資源只能對(duì)應(yīng)一個(gè)對(duì)象,在上面的程序中,我們創(chuàng)建了四個(gè)ThreadTest對(duì)象,就等于創(chuàng)建了四個(gè)資源,每個(gè)資源都有100張票,每個(gè)線程都在獨(dú)自處理各自的資源。
            經(jīng)過(guò)這些實(shí)驗(yàn)和分析,可以總結(jié)出,要實(shí)現(xiàn)這個(gè)鐵路售票程序,我們只能創(chuàng)建一個(gè)資源對(duì)象,但要?jiǎng)?chuàng)建多個(gè)線程去處理同一個(gè)資源對(duì)象,并且每個(gè)線程上所運(yùn)行的是相同的程序代碼。在回顧一下使用接口編寫(xiě)多線程的過(guò)程。
           public class ThreadDemo1
            
          public static void main(String[] args)
            ThreadTest t 
          = new ThreadTest(); 
            
          new Thread(t).start(); 
            
          new Thread(t).start(); 
            
          new Thread(t).start(); 
            
          new Thread(t).start(); 
            }
           
            }
           
            
          class ThreadTest implements Runnable
            
          private int tickets = 100
            
          public void run()
            
          while(true)
            
          if(tickets > 0)
            System.out.println(Thread.currentThread().getName() 
          + 
            
          " is saling ticket " + tickets--); 
            }
           
            }
           
            }
           
            }

          上面的程序中,創(chuàng)建了四個(gè)線程,每個(gè)線程調(diào)用的是同一個(gè)ThreadTest對(duì)象中的run()方法,訪問(wèn)的是同一個(gè)對(duì)象中的變量(tickets)的實(shí)例,這個(gè)程序滿足了我們的需求。在Windows上可以啟動(dòng)多個(gè)記事本程序一樣,也就是多個(gè)進(jìn)程使用同一個(gè)記事本程序代碼。
            可見(jiàn),實(shí)現(xiàn)Runnable接口相對(duì)于繼承Thread類來(lái)說(shuō),有如下顯著的好處:
            (1)適合多個(gè)相同程序代碼的線程去處理同一資源的情況,把虛擬CPU(線程)同程序的代碼,數(shù)據(jù)有效的分離,較好地體現(xiàn)了面向?qū)ο蟮脑O(shè)計(jì)思想。
            (2)可以避免由于Java的單繼承特性帶來(lái)的局限。我們經(jīng)常碰到這樣一種情況,即當(dāng)我們要將已經(jīng)繼承了某一個(gè)類的子類放入多線程中,由于一個(gè)類不能同時(shí)有兩個(gè)父類,所以不能用繼承Thread類的方式,那么,這個(gè)類就只能采用實(shí)現(xiàn)Runnable接口的方式了。
            (3)有利于程序的健壯性,代碼能夠被多個(gè)線程共享,代碼與數(shù)據(jù)是獨(dú)立的。當(dāng)多個(gè)線程的執(zhí)行代碼來(lái)自同一個(gè)類的實(shí)例時(shí),即稱它們共享相同的代碼。多個(gè)線程操作相同的數(shù)據(jù),與它們的代碼無(wú)關(guān)。當(dāng)共享訪問(wèn)相同的對(duì)象時(shí),即它們共享相同的數(shù)據(jù)。當(dāng)線程被構(gòu)造時(shí),需要的代碼和數(shù)據(jù)通過(guò)一個(gè)對(duì)象作為構(gòu)造函數(shù)實(shí)參傳遞進(jìn)去,這個(gè)對(duì)象就是一個(gè)實(shí)現(xiàn)了Runnable接口的類的實(shí)例。
          posted on 2010-02-23 09:19 Mison 閱讀(190) 評(píng)論(0)  編輯  收藏

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


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 宁都县| 永胜县| 石台县| 敦化市| 高陵县| 屏东市| 泸州市| 泾川县| 庐江县| 怀来县| 仙桃市| 日喀则市| 修武县| 洪雅县| 乡城县| 周至县| 南华县| 麻江县| 泸州市| 南安市| 阿巴嘎旗| 河北省| 嘉黎县| 株洲市| 平阳县| 高雄县| 伊川县| 翁牛特旗| 美姑县| 舞钢市| 拜城县| 武穴市| 黄骅市| 新化县| 荣成市| 浪卡子县| 合山市| 达日县| 大厂| 晋中市| 佳木斯市|