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

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

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

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

              從線程中返回數(shù)據(jù)和向線程傳遞數(shù)據(jù)類似。也可以通過類成員以及回調(diào)函數(shù)來返回數(shù)據(jù)。但類成員在返回數(shù)據(jù)和傳遞數(shù)據(jù)時有一些區(qū)別,下面讓我們來看看它們區(qū)別在哪。

          一、通過類變量和方法返回數(shù)據(jù)

          使用這種方法返回數(shù)據(jù)需要在調(diào)用start方法后才能通過類變量或方法得到數(shù)據(jù)。讓我們先來看看例程2-13會得到什么結(jié)果。

          package mythread;

          public class MyThread extends Thread
          {
             
          private String value1;
              
          private String value2;

              
          public void run()
              {
                  value1 
          = "通過成員變量返回數(shù)據(jù)";
                  value2 
          = "通過成員方法返回數(shù)據(jù)";
              }
              
          public static void main(String[] args) throws Exception
              {
                  MyThread thread 
          = new MyThread();
                  thread.start();
                  System.out.println(
          "value1:" + thread.value1);
                  System.out.println(
          "value2:" + thread.value2);
              }
          }

           

          運(yùn)行上面的代碼有可能輸出如下的結(jié)果:

          value1:null
          value2:null

          從上面的運(yùn)行結(jié)果看很不正常。在run方法中已經(jīng)對value1value2賦了值,而返回的卻是null。發(fā)生這種情況的原因是調(diào)用start方法后就立刻輸出了value1和value2的值,而這里run方法還沒有執(zhí)行到為value1和value2賦值的語句。要避免這種情況的發(fā)生,就需要等run方法執(zhí)行完后才執(zhí)行輸出value1和value2的代碼。因此,我們可以想到使用sleep方法將主線程進(jìn)行延遲,如可以在thread.start()后加一行如下的語句:

          sleep(1000);

          這樣做可以使主線程延遲1秒后再往下執(zhí)行,但這樣做有一個問題,就是我們怎么知道要延遲多長時間。在這個例子的run方法中只有兩條賦值語句,而且只創(chuàng)建了一個線程,因此,延遲1秒已經(jīng)足夠,但如果run方法中的語句很復(fù)雜,這個時間就很難預(yù)測,因此,這種方法并不穩(wěn)定。

          我們的目的就是得到value1value2的值,因此,只要判斷value1value2是否為null。如果它們都不為null時,就可以輸出這兩個值了。我們可以使用如下的代碼來達(dá)到這個目的:

          while (thread.value1 == null || thread.value2 == null);

          使用上面的語句可以很穩(wěn)定地避免這種情況發(fā)生,但這種方法太耗費(fèi)系統(tǒng)資源。大家可以設(shè)想,如果run方法中的代碼很復(fù)雜,value1value2需要很長時間才能被賦值,這樣while循環(huán)就必須一直執(zhí)行下去,直到value1value2都不為空為止。因此,我們可以對上面的語句做如下的改進(jìn):

          while (thread.value1 == null || thread.value2 == null)
              sleep(
          100);

           

          while循環(huán)中第判斷一次value1value2的值后休眠100毫秒,然后再判斷這兩個值。這樣所占用的系統(tǒng)資源會小一些。

          上面的方法雖然可以很好地解決,但Java的線程模型為我們提供了更好的解決方案,這就是join方法。在前面已經(jīng)討論過,join的功能就是使用線程從異步執(zhí)行變成同步執(zhí)行。當(dāng)線程變成同步執(zhí)行后,就和從普通的方法中得到返回數(shù)據(jù)沒有什么區(qū)別了。因此,可以使用如下的代碼更有效地解決這個問題:


          thread.start();
          thread.join();

              在thread.join()執(zhí)行完后,線程threadrun方法已經(jīng)退出了,也就是說線程thread已經(jīng)結(jié)束了。因此,在thread.join()后面可以放心大膽地使用MyThread類的任何資源來得到返回數(shù)據(jù)。 

          二、通過回調(diào)函數(shù)返回數(shù)據(jù)

              其實這種方法已經(jīng)在《向線程傳遞數(shù)據(jù)的三種方法》中介紹了。《向線程傳遞數(shù)據(jù)的三種方法》一文的例子中通過Work類的process方法向線程中傳遞了計算結(jié)果,但同時,也通過process方法從線程中得到了三個隨機(jī)數(shù)。因此,這種方法既可以向線程中傳遞數(shù)據(jù),也可以從線程中獲得數(shù)據(jù)。

          下一篇:
          Java多線程初學(xué)者指南(9):為什么要進(jìn)行數(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-19 13:02 銀河使者 閱讀(6914) 評論(0)  編輯  收藏 所屬分類: java 、 原創(chuàng) 、多線程

          主站蜘蛛池模板: 星子县| 长宁县| 金山区| 承德县| 长乐市| 明水县| 汝南县| 江川县| 定兴县| 宁城县| 土默特右旗| 宜都市| 长宁县| 钟山县| 项城市| 尼木县| 察雅县| 屏山县| 涟源市| 永和县| 离岛区| 屯昌县| 蛟河市| 武威市| 汶上县| 宁陕县| 保靖县| 凉山| 义乌市| 昔阳县| 新建县| 五峰| 寿光市| 临沧市| 承德市| 二连浩特市| 昆明市| 通辽市| 浠水县| 望城县| 普格县|