ALL is Well!

          敏捷是一條很長的路,摸索著前進著

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            30 隨筆 :: 23 文章 :: 71 評論 :: 0 Trackbacks

          一、在研究join的用法之前,先明確兩件事情。

          1.join方法定義在Thread類中,則調用者必須是一個線程,

          例如:

          Thread t = new CustomThread();//這里一般是自定義的線程類

          t.start();//線程起動

          t.join();//此處會拋出InterruptedException異常

           

          2.上面的兩行代碼也是在一個線程里面執行的。

           

          以上出現了兩個線程,一個是我們自定義的線程類,我們實現了run方法,做一些我們需要的工作;另外一個線程,生成我們自定義線程類的對象,然后執行

          customThread.start();

          customThread.join();

          在這種情況下,兩個線程的關系是一個線程由另外一個線程生成并起動,所以我們暫且認為第一個線程叫做“子線程”,另外一個線程叫做“主線程”。

           

          二、為什么要用join()方法

          主線程生成并起動了子線程,而子線程里要進行大量的耗時的運算(這里可以借鑒下線程的作用),當主線程處理完其他的事務后,需要用到子線程的處理結果,這個時候就要用到join();方法了。

           

           

          三、join方法的作用

          在網上看到有人說“將兩個線程合并”。這樣解釋我覺得理解起來還更麻煩。不如就借鑒下API里的說法:

          “等待該線程終止。”

          解釋一下,是主線程(我在“一”里已經命名過了)等待子線程的終止。也就是在子線程調用了join()方法后面的代碼,只有等到子線程結束了才能執行。(Waits for this thread to die.)

           

           

          四、用實例來理解

          寫一個簡單的例子來看一下join()的用法,一共三個類:

          1.CustomThread 類

          2. CustomThread1類

          3. JoinTestDemo 類,main方法所在的類。

           

          代碼1:

           1package wxhx.csdn2;   
           2/**  
           3 *   
           4 * @author bzwm  
           5 *  
           6 */
            
           7class CustomThread1 extends Thread {   
           8    public CustomThread1() {   
           9        super("[CustomThread1] Thread");   
          10    }
          ;   
          11    public void run() {   
          12        String threadName = Thread.currentThread().getName();   
          13        System.out.println(threadName + " start.");   
          14        try {   
          15            for (int i = 0; i < 5; i++{   
          16                System.out.println(threadName + " loop at " + i);   
          17                Thread.sleep(1000);   
          18            }
             
          19            System.out.println(threadName + " end.");   
          20        }
           catch (Exception e) {   
          21            System.out.println("Exception from " + threadName + ".run");   
          22        }
             
          23    }
             
          24}
             
          25class CustomThread extends Thread {   
          26    CustomThread1 t1;   
          27    public CustomThread(CustomThread1 t1) {   
          28        super("[CustomThread] Thread");   
          29        this.t1 = t1;   
          30    }
             
          31    public void run() {   
          32        String threadName = Thread.currentThread().getName();   
          33        System.out.println(threadName + " start.");   
          34        try {   
          35            t1.join();   
          36            System.out.println(threadName + " end.");   
          37        }
           catch (Exception e) {   
          38            System.out.println("Exception from " + threadName + ".run");   
          39        }
             
          40    }
             
          41}
             
          42public class JoinTestDemo {   
          43    public static void main(String[] args) {   
          44        String threadName = Thread.currentThread().getName();   
          45        System.out.println(threadName + " start.");   
          46        CustomThread1 t1 = new CustomThread1();   
          47        CustomThread t = new CustomThread(t1);   
          48        try {   
          49            t1.start();   
          50            Thread.sleep(2000);   
          51            t.start();   
          52            t.join();//在代碼2里,將此處注釋掉   
          53        }
           catch (Exception e) {   
          54            System.out.println("Exception from main");   
          55        }
             
          56        System.out.println(threadName + " end!");   
          57    }
             
          58}


          打印結果:

           

          main start.//main方法所在的線程起動,但沒有馬上結束,因為調用t.join();,所以要等到t結束了,此線程才能向下執行。

          [CustomThread1] Thread start.//線程CustomThread1起動

          [CustomThread1] Thread loop at 0//線程CustomThread1執行

          [CustomThread1] Thread loop at 1//線程CustomThread1執行

          [CustomThread] Thread start.//線程CustomThread起動,但沒有馬上結束,因為調用t1.join();,所以要等到t1結束了,此線程才能向下執行。

          [CustomThread1] Thread loop at 2//線程CustomThread1繼續執行

          [CustomThread1] Thread loop at 3//線程CustomThread1繼續執行

          [CustomThread1] Thread loop at 4//線程CustomThread1繼續執行

          [CustomThread1] Thread end. //線程CustomThread1結束了

          [CustomThread] Thread end.// 線程CustomThread在t1.join();阻塞處起動,向下繼續執行的結果

          main end!//線程CustomThread結束,此線程在t.join();阻塞處起動,向下繼續執行的結果。

           

          修改一下代碼,得到代碼2:(這里只寫出修改的部分)

           

           1public class JoinTestDemo {   
           2    public static void main(String[] args) {   
           3        String threadName = Thread.currentThread().getName();   
           4        System.out.println(threadName + " start.");   
           5        CustomThread1 t1 = new CustomThread1();   
           6        CustomThread t = new CustomThread(t1);   
           7        try {   
           8            t1.start();   
           9            Thread.sleep(2000);   
          10            t.start();   
          11//          t.join();//在代碼2里,將此處注釋掉   
          12        }
           catch (Exception e) {   
          13            System.out.println("Exception from main");   
          14        }
             
          15        System.out.println(threadName + " end!");   
          16    }
             
          17}


          打印結果:

           

          main start. // main方法所在的線程起動,但沒有馬上結束,這里并不是因為join方法,而是因為Thread.sleep(2000);

          [CustomThread1] Thread start. //線程CustomThread1起動

          [CustomThread1] Thread loop at 0//線程CustomThread1執行

          [CustomThread1] Thread loop at 1//線程CustomThread1執行

          main end!// Thread.sleep(2000);結束,雖然在線程CustomThread執行了t1.join();,但這并不會影響到其他線程(這里main方法所在的線程)。

          [CustomThread] Thread start. //線程CustomThread起動,但沒有馬上結束,因為調用t1.join();,所以要等到t1結束了,此線程才能向下執行。

          [CustomThread1] Thread loop at 2//線程CustomThread1繼續執行

          [CustomThread1] Thread loop at 3//線程CustomThread1繼續執行

          [CustomThread1] Thread loop at 4//線程CustomThread1繼續執行

          [CustomThread1] Thread end. //線程CustomThread1結束了

          [CustomThread] Thread end. // 線程CustomThread在t1.join();阻塞處起動,向下繼續執行的結果

           

           

          五、從源碼看join()方法

           

          在CustomThread的run方法里,執行了t1.join();,進入看一下它的JDK源碼:

           

          1public final void join() throws InterruptedException {   
          2join(0);   
          3}
            

          然后進入join(0)方法:

           1   /**  
           2    * Waits at most <code>millis</code> milliseconds for this thread to   
           3    * die. A timeout of <code>0</code> means to wait forever. //注意這句  
           4    *  
           5    * @param      millis   the time to wait in milliseconds.  
           6    * @exception  InterruptedException if another thread has interrupted  
           7    *             the current thread.  The <i>interrupted status</i> of the  
           8    *             current thread is cleared when this exception is thrown.  
           9    */
            
          10   public final synchronized void join(long millis) //參數millis為0.   
          11   throws InterruptedException {   
          12long base = System.currentTimeMillis();   
          13long now = 0;   
          14if (millis < 0{   
          15           throw new IllegalArgumentException("timeout value is negative");   
          16}
             
          17if (millis == 0{//進入這個分支   
          18    while (isAlive()) {//判斷本線程是否為活動的。這里的本線程就是t1.   
          19    wait(0);//阻塞   
          20    }
             
          21}
           else {   
          22    while (isAlive()) {   
          23    long delay = millis - now;   
          24    if (delay <= 0{   
          25        break;   
          26    }
             
          27    wait(delay);   
          28    now = System.currentTimeMillis() - base;   
          29    }
             
          30}
             
          31   }
           

           

          單純從代碼上看,如果線程被生成了,但還未被起動,調用它的join()方法是沒有作用的。將直接繼續向下執行,這里就不寫代碼驗證了。

          ----2009年02月12日

          posted on 2010-09-01 11:52 李 明 閱讀(56018) 評論(16)  編輯  收藏 所屬分類: J2SE技術知識

          評論

          # re: 淺析 Java Thread.join()[未登錄] 2011-10-10 10:11 test
          二、為什么要用join()方法

          主線程生成并起動了子線程,而子線程里要進行大量的耗時的運算(這里可以借鑒下線程的作用),當主線程處理完其他的事務后,需要用到子線程的處理結果,這個時候就要用到join();方法了。

          ????????????????????
          感覺這段很成問題  回復  更多評論
            

          # re: 淺析 Java Thread.join() 2011-10-29 13:25 zhangyou1010
          t.start();//線程起動

          t.join();//此處會拋出InterruptedException異常

          上面這段代碼,不會異常啊。  回復  更多評論
            

          # re: 淺析 Java Thread.join()[未登錄] 2013-03-21 11:37 minelibra
          就像主線程是開會一樣,會議(主線程)正在進行中,這時候需要一個人join進來(子線程啟動),并執行他自己的操作,如果他的操作沒有執行完畢,則會議(主線程)不能結束。  回復  更多評論
            

          # re: 淺析 Java Thread.join() 2013-05-11 00:05 億可達西靚
          @test
          比如:你準備洗澡,需要準備的步驟,準備好衣服,沐浴的東西及燒水這些事情,由于燒水耗時太長,如果也放在主線程之中,就很浪費資源,所以如果我們另開線程去處理,就會達到很好效果,于是乎在準備好衣服,沐浴的東西之前就去開子線程燒水,燒水的過程中主線程準備好衣服,沐浴的東西,此時就等待水燒好,然后方可痛快的洗澡了!!  回復  更多評論
            

          # re: 淺析 Java Thread.join() 2013-07-25 14:44 emmet7life
          @minelibra
          這個解釋不錯喲  回復  更多評論
            

          # re: 淺析 Java Thread.join()[未登錄] 2013-09-12 07:08 Mark
          這個簡單的東西,你搞那么復雜。主線程等待調用join方法的子線程執行結束后再繼續執行  回復  更多評論
            

          # re: 淺析 Java Thread.join()[未登錄] 2013-12-12 10:15 Jack
          @Mark
          說的對  回復  更多評論
            

          # re: 淺析 Java Thread.join() 2014-06-12 16:41 11
          什么問題?@test
            回復  更多評論
            

          # re: 淺析 Java Thread.join()[未登錄] 2014-06-17 14:25 YY
          你和朋友一起吃飯,突然你肚子痛,要拉屎,這個時候你去了廁所拉屎,拉了很久,但是你的朋友們要等你拉完回來在一起AA  回復  更多評論
            

          # re: 淺析 Java Thread.join() 2014-06-17 14:30 @YY
          精辟  回復  更多評論
            

          # re: 淺析 Java Thread.join() 2014-06-17 14:35 頭很大
          @YY
          這..... 這個知識點 我懂了  回復  更多評論
            

          # re: 淺析 Java Thread.join() 2014-08-19 14:31 reiike
          麻煩樓主把文章理一理,這么混亂不清還寫篇文章,服了。  回復  更多評論
            

          # re: 淺析 Java Thread.join() 2014-08-19 14:36 reiike

          http://www.open-open.com/lib/view/open1371741636171.html

          別人的文章,論文章排版,整潔干凈,論解釋,邏輯清晰,前后連貫。  回復  更多評論
            

          # re: 淺析 Java Thread.join() 2014-10-09 09:09 chanedi
          @reiike
          這兩個文章不是一樣嗎?  回復  更多評論
            

          # re: 淺析 Java Thread.join()[未登錄] 2014-12-26 16:47 peter
          @YY
          這個解釋口味好重  回復  更多評論
            

          主站蜘蛛池模板: 长治市| 财经| 武平县| 通城县| 调兵山市| 三原县| 云林县| 洛扎县| 津市市| 泸州市| 桂东县| 顺昌县| 怀来县| 临潭县| 沾化县| 巴彦淖尔市| 华安县| 澄城县| 南召县| 华阴市| 石首市| 文水县| 简阳市| 如皋市| 晴隆县| 普洱| 香港| 邓州市| 福海县| 乌兰察布市| 綦江县| 古蔺县| 攀枝花市| 黔西| 墨脱县| 渑池县| 高密市| 容城县| 景东| 潮安县| 霍山县|