隨筆 - 312, 文章 - 14, 評論 - 1393, 引用 - 0
          數(shù)據(jù)加載中……

          Java多線程初學者指南(7):向線程傳遞數(shù)據(jù)的三種方法

          本文為原創(chuàng),如需轉(zhuǎn)載,請注明作者和出處,謝謝!

          上一篇:Java多線程初學者指南(6):慎重使用volatile關(guān)鍵字

          在傳統(tǒng)的同步開發(fā)模式下,當我們調(diào)用一個函數(shù)時,通過這個函數(shù)的參數(shù)將數(shù)據(jù)傳入,并通過這個函數(shù)的返回值來返回最終的計算結(jié)果。但在多線程的異步開發(fā)模式下,數(shù)據(jù)的傳遞和返回和同步開發(fā)模式有很大的區(qū)別。由于線程的運行和結(jié)束是不可預(yù)料的,因此,在傳遞和返回數(shù)據(jù)時就無法象函數(shù)一樣通過函數(shù)參數(shù)和return語句來返回數(shù)據(jù)。本文就以上原因介紹了幾種用于向線程傳遞數(shù)據(jù)的方法,在下一篇文章中將介紹從線程中返回數(shù)據(jù)的方法。

              欲先取之,必先予之。一般在使用線程時都需要有一些初始化數(shù)據(jù),然后線程利用這些數(shù)據(jù)進行加工處理,并返回結(jié)果。在這個過程中最先要做的就是向線程中傳遞數(shù)據(jù)。

          一、通過構(gòu)造方法傳遞數(shù)據(jù)

          在創(chuàng)建線程時,必須要建立一個Thread類的或其子類的實例。因此,我們不難想到在調(diào)用start方法之前通過線程類的構(gòu)造方法將數(shù)據(jù)傳入線程。并將傳入的數(shù)據(jù)使用類變量保存起來,以便線程使用(其實就是在run方法中使用)。下面的代碼演示了如何通過構(gòu)造方法來傳遞數(shù)據(jù):

          package mythread;

          public class MyThread1 extends Thread
          {
              
          private String name;

              
          public MyThread1(String name)
              {
                  
          this.name = name;
              }
              
          public void run()
              {
                  System.out.println(
          "hello " + name);
              }
              
          public static void main(String[] args)
              {
                  Thread thread 
          = new MyThread1("world");
                  thread.start();       
              }
          }

              由于這種方法是在創(chuàng)建線程對象的同時傳遞數(shù)據(jù)的,因此,在線程運行之前這些數(shù)據(jù)就就已經(jīng)到位了,這樣就不會造成數(shù)據(jù)在線程運行后才傳入的現(xiàn)象。如果要傳遞更復(fù)雜的數(shù)據(jù),可以使用集合、類等數(shù)據(jù)結(jié)構(gòu)。使用構(gòu)造方法來傳遞數(shù)據(jù)雖然比較安全,但如果要傳遞的數(shù)據(jù)比較多時,就會造成很多不便。由于Java沒有默認參數(shù),要想實現(xiàn)類似默認參數(shù)的效果,就得使用重載,這樣不但使構(gòu)造方法本身過于復(fù)雜,又會使構(gòu)造方法在數(shù)量上大增。因此,要想避免這種情況,就得通過類方法或類變量來傳遞數(shù)據(jù)。

          二、通過變量和方法傳遞數(shù)據(jù)

              向?qū)ο笾袀魅霐?shù)據(jù)一般有兩次機會,第一次機會是在建立對象時通過構(gòu)造方法將數(shù)據(jù)傳入,另外一次機會就是在類中定義一系列的public的方法或變量(也可稱之為字段)。然后在建立完對象后,通過對象實例逐個賦值。下面的代碼是對MyThread1類的改版,使用了一個setName方法來設(shè)置name變量:

          package mythread;

          public class MyThread2 implements Runnable
          {
              
          private String name;

              
          public void setName(String name)
              {
                  
          this.name = name;
              }
              
          public void run()
              {
                  System.out.println(
          "hello " + name);
              }
              
          public static void main(String[] args)
              {
                  MyThread2 myThread 
          = new MyThread2();
                  myThread.setName(
          "world");
                  Thread thread 
          = new Thread(myThread);
                  thread.start();
              }
          }

          三、通過回調(diào)函數(shù)傳遞數(shù)據(jù)

              上面討論的兩種向線程中傳遞數(shù)據(jù)的方法是最常用的。但這兩種方法都是main方法中主動將數(shù)據(jù)傳入線程類的。這對于線程來說,是被動接收這些數(shù)據(jù)的。然而,在有些應(yīng)用中需要在線程運行的過程中動態(tài)地獲取數(shù)據(jù),如在下面代碼run方法中產(chǎn)生了3個隨機數(shù),然后通過Work類的process方法求這三個隨機數(shù)的和,并通過Data類的value將結(jié)果返回。從這個例子可以看出,在返回value之前,必須要得到三個隨機數(shù)。也就是說,這個value是無法事先就傳入線程類的。

          package mythread;

          class Data
          {
              
          public int value = 0;
          }
          class Work
          {
              
          public void process(Data data, Integer numbers)
              {
                  
          for (int n : numbers)
                  {
                      data.value 
          += n;
                  }
              }
          }
          public class MyThread3 extends Thread
          {
              
          private Work work;

              
          public MyThread3(Work work)
              {
                  
          this.work = work;
              }
              
          public void run()
              {
                  java.util.Random random 
          = new java.util.Random();
                  Data data 
          = new Data();
                  
          int n1 = random.nextInt(1000);
                  
          int n2 = random.nextInt(2000);
                  
          int n3 = random.nextInt(3000);
                  work.process(data, n1, n2, n3);   
          // 使用回調(diào)函數(shù)
                  System.out.println(String.valueOf(n1) + "+" + String.valueOf(n2) + "+"
                          
          + String.valueOf(n3) + "=" + data.value);
              }
              
          public static void main(String[] args)
              {
                  Thread thread 
          = new MyThread3(new Work());
                  thread.start();
              }
          }

          在上面代碼中的process方法被稱為回調(diào)函數(shù)。從本質(zhì)上說,回調(diào)函數(shù)就是事件函數(shù)。在Windows API中常使用回調(diào)函數(shù)和調(diào)用API的程序之間進行數(shù)據(jù)交互。因此,調(diào)用回調(diào)函數(shù)的過程就是最原始的引發(fā)事件的過程。在這個例子中調(diào)用了process方法來獲得數(shù)據(jù)也就相當于在run方法中引發(fā)了一個事件。

          下一篇:
          Java多線程初學者指南(8):從線程返回數(shù)據(jù)的兩種方法





          Android開發(fā)完全講義(第2版)(本書版權(quán)已輸出到臺灣)

          http://product.dangdang.com/product.aspx?product_id=22741502



          Android高薪之路:Android程序員面試寶典 http://book.360buy.com/10970314.html


          新浪微博:http://t.sina.com.cn/androidguy   昵稱:李寧_Lining

          posted on 2009-03-16 23:18 銀河使者 閱讀(15839) 評論(2)  編輯  收藏 所屬分類: java 原創(chuàng)多線程

          評論

          # re: Java多線程初學者指南(7):向線程傳遞數(shù)據(jù)的三種方法  回復(fù)  更多評論   

          Pipe
          2009-03-19 12:16 | 隔葉黃鶯

          # re: Java多線程初學者指南(7):向線程傳遞數(shù)據(jù)的三種方法[未登錄]  回復(fù)  更多評論   

          錯誤太多,不要誤人子弟了
          2016-02-04 11:24 | test
          主站蜘蛛池模板: 宕昌县| 栾城县| 阿拉尔市| 同心县| 大姚县| 白玉县| 千阳县| 桐城市| 安顺市| 平定县| 望江县| 乐昌市| 葵青区| 黔南| 航空| 舒兰市| 无为县| 南漳县| 临澧县| 泸定县| 乐至县| 中江县| 夹江县| 吉安县| 兴城市| 黄大仙区| 灵川县| 凤山县| 荣昌县| 济南市| 平潭县| 加查县| 海安县| 水城县| 沂源县| 江安县| 肃南| 柳林县| 邹平县| 紫阳县| 石景山区|