posts - 110, comments - 101, trackbacks - 0, articles - 7
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          java 多線程 Thread與Runnable的區別

          Posted on 2011-11-08 20:46 云云 閱讀(643) 評論(1)  編輯  收藏
          在java中可有兩種方式實現多線程,一種是繼承Thread類,一種是實現Runnable接口;Thread類是在java.lang包中定義的。一個類只要繼承了Thread類同時覆寫了本類中的run()方法就可以實現多線程操作了,但是一個類只能繼承一個父類,這是此方法的局限,下面看例子:
          package org.thread.demo;
          class MyThread extends Thread{
          private String name;
          public MyThread(String name) {
          super();
          this.name = name;
          }
          public void run(){
          for(int i=0;i<10;i++){
          System.out.println("線程開始:"+this.name+",i="+i);
          }
          }
          }

          package org.thread.demo;
          public class ThreadDemo01 {
          public static void main(String[] args) {
          MyThread mt1=new MyThread("線程a");
          MyThread mt2=new MyThread("線程b");
          mt1.run();
          mt2.run();
          }
          }
          但是,此時結果很有規律,先第一個對象執行,然后第二個對象執行,并沒有相互運行。在JDK的文檔中可以發現,一旦調用start()方法,則會通過 JVM找到run()方法。下面啟動
          start()方法啟動線程:
          package org.thread.demo;
          public class ThreadDemo01 {
          public static void main(String[] args) {
          MyThread mt1=new MyThread("線程a");
          MyThread mt2=new MyThread("線程b");
          mt1.start();
          mt2.start();
          }
          };

          這樣程序可以正常完成交互式運行。那么為啥非要使用start();方法啟動多線程呢?
          在JDK的安裝路徑下,src.zip是全部的java源程序,通過此代碼找到Thread中的start()方法的定義,可以發現此方法中使用了 private native void start0();其中native關鍵字表示可以調用操作系統的底層函數,那么這樣的技術成為JNI技術(java Native Interface)

          Runnable接口
          在實際開發中一個多線程的操作很少使用Thread類,而是通過Runnable接口完成。
          public interface Runnable{
          public void run();
          }
          例子:
          package org.runnable.demo;
          class MyThread implements Runnable{
          private String name;
          public MyThread(String name) {
          this.name = name;
          }
          public void run(){
          for(int i=0;i<100;i++){
          System.out.println("線程開始:"+this.name+",i="+i);
          }
          }
          };
          但是在使用Runnable定義的子類中沒有start()方法,只有Thread類中才有。此時觀察Thread類,有一個構造方法:public Thread(Runnable targer)
          此構造方法接受Runnable的子類實例,也就是說可以通過Thread類來啟動Runnable實現的多線程。(start()可以協調系統的資源):
          package org.runnable.demo;
          import org.runnable.demo.MyThread;
          public class ThreadDemo01 {
          public static void main(String[] args) {
          MyThread mt1=new MyThread("線程a");
          MyThread mt2=new MyThread("線程b");
          new Thread(mt1).start();
          new Thread(mt2).start();
          }
          }
          兩種實現方式的區別和聯系:
          在程序開發中只要是多線程肯定永遠以實現Runnable接口為主,因為實現Runnable接口相比繼承Thread類有如下好處:
          ->避免點繼承的局限,一個類可以繼承多個接口。
          ->適合于資源的共享
          以賣票程序為例,通過Thread類完成:
          package org.demo.dff;
          class MyThread extends Thread{
          private int ticket=10;
          public void run(){
          for(int i=0;i<20;i++){
          if(this.ticket>0){
          System.out.println("賣票:ticket"+this.ticket--);
          }
          }
          }
          };
          下面通過三個線程對象,同時賣票:
          package org.demo.dff;
          public class ThreadTicket {
          public static void main(String[] args) {
          MyThread mt1=new MyThread();
          MyThread mt2=new MyThread();
          MyThread mt3=new MyThread();
          mt1.start();//每個線程都各賣了10張,共賣了30張票
          mt2.start();//但實際只有10張票,每個線程都賣自己的票
          mt3.start();//沒有達到資源共享
          }
          }
          如果用Runnable就可以實現資源共享,下面看例子:
          package org.demo.runnable;
          class MyThread implements Runnable{
          private int ticket=10;
          public void run(){
          for(int i=0;i<20;i++){
          if(this.ticket>0){
          System.out.println("賣票:ticket"+this.ticket--);
          }
          }
          }
          }
          package org.demo.runnable;
          public class RunnableTicket {
          public static void main(String[] args) {
          MyThread mt=new MyThread();
          new Thread(mt).start();//同一個mt,但是在Thread中就不可以,如果用同一
          new Thread(mt).start();//個實例化對象mt,就會出現異常
          new Thread(mt).start();
          }
          };
          雖然現在程序中有三個線程,但是一共賣了10張票,也就是說使用Runnable實現多線程可以達到資源共享目的。

          Runnable接口和Thread之間的聯系:
          public class Thread extends Object implements Runnable
          發現Thread類也是Runnable接口的子類。

          因為一個線程只能啟動一次,通過Thread實現線程時,線程和線程所要執行的任務是捆綁在一起的。也就使得一個任務只能啟動一個線程,不同的線程執行的任務是不相同的,所以沒有必要,也不能讓兩個線程共享彼此任務中的資源。

          一個任務可以啟動多個線程,通過Runnable方式實現的線程,實際是開辟一個線程,將任務傳遞進去,由此線程執行。可以實例化多個 Thread對象,將同一任務傳遞進去,也就是一個任務可以啟動多個線程來執行它。這些線程執行的是同一個任務,所以他們的資源是共享。

          兩種不同的線程實現方式本身就決定了其是否能進行資源共享。



          評論

          # re: java 多線程 Thread與Runnable的區別  回復  更多評論   

          2012-02-17 11:19 by 初入江湖
          寫的不錯

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


          網站導航:
           
          主站蜘蛛池模板: 徐水县| 天峨县| 乐山市| 福贡县| 泗洪县| 梁平县| 临西县| 盖州市| 文山县| 洛浦县| 丹凤县| 车致| 同心县| 互助| 塘沽区| 额济纳旗| 津市市| 武城县| 调兵山市| 浦东新区| 莫力| 宣汉县| 建湖县| 塔城市| 巴东县| 泰来县| 静宁县| 冷水江市| 曲周县| 周口市| 大荔县| 济宁市| 荣昌县| 右玉县| 嘉兴市| 汕头市| 沙洋县| 江北区| 罗定市| 大竹县| 娄底市|