<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    ALL is Well!

    敏捷是一條很長(zhǎng)的路,摸索著前進(jìn)著

      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      30 隨筆 :: 23 文章 :: 71 評(píng)論 :: 0 Trackbacks

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

    1.join方法定義在Thread類中,則調(diào)用者必須是一個(gè)線程,

    例如:

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

    t.start();//線程起動(dòng)

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

     

    2.上面的兩行代碼也是在一個(gè)線程里面執(zhí)行的。

     

    以上出現(xiàn)了兩個(gè)線程,一個(gè)是我們自定義的線程類,我們實(shí)現(xiàn)了run方法,做一些我們需要的工作;另外一個(gè)線程,生成我們自定義線程類的對(duì)象,然后執(zhí)行

    customThread.start();

    customThread.join();

    在這種情況下,兩個(gè)線程的關(guān)系是一個(gè)線程由另外一個(gè)線程生成并起動(dòng),所以我們暫且認(rèn)為第一個(gè)線程叫做“子線程”,另外一個(gè)線程叫做“主線程”。

     

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

    主線程生成并起動(dòng)了子線程,而子線程里要進(jìn)行大量的耗時(shí)的運(yùn)算(這里可以借鑒下線程的作用),當(dāng)主線程處理完其他的事務(wù)后,需要用到子線程的處理結(jié)果,這個(gè)時(shí)候就要用到j(luò)oin();方法了。

     

     

    三、join方法的作用

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

    “等待該線程終止。”

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

     

     

    四、用實(shí)例來理解

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

    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}


    打印結(jié)果:

     

    main start.//main方法所在的線程起動(dòng),但沒有馬上結(jié)束,因?yàn)檎{(diào)用t.join();,所以要等到t結(jié)束了,此線程才能向下執(zhí)行。

    [CustomThread1] Thread start.//線程CustomThread1起動(dòng)

    [CustomThread1] Thread loop at 0//線程CustomThread1執(zhí)行

    [CustomThread1] Thread loop at 1//線程CustomThread1執(zhí)行

    [CustomThread] Thread start.//線程CustomThread起動(dòng),但沒有馬上結(jié)束,因?yàn)檎{(diào)用t1.join();,所以要等到t1結(jié)束了,此線程才能向下執(zhí)行。

    [CustomThread1] Thread loop at 2//線程CustomThread1繼續(xù)執(zhí)行

    [CustomThread1] Thread loop at 3//線程CustomThread1繼續(xù)執(zhí)行

    [CustomThread1] Thread loop at 4//線程CustomThread1繼續(xù)執(zhí)行

    [CustomThread1] Thread end. //線程CustomThread1結(jié)束了

    [CustomThread] Thread end.// 線程CustomThread在t1.join();阻塞處起動(dòng),向下繼續(xù)執(zhí)行的結(jié)果

    main end!//線程CustomThread結(jié)束,此線程在t.join();阻塞處起動(dòng),向下繼續(xù)執(zhí)行的結(jié)果。

     

    修改一下代碼,得到代碼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}


    打印結(jié)果:

     

    main start. // main方法所在的線程起動(dòng),但沒有馬上結(jié)束,這里并不是因?yàn)閖oin方法,而是因?yàn)門hread.sleep(2000);

    [CustomThread1] Thread start. //線程CustomThread1起動(dòng)

    [CustomThread1] Thread loop at 0//線程CustomThread1執(zhí)行

    [CustomThread1] Thread loop at 1//線程CustomThread1執(zhí)行

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

    [CustomThread] Thread start. //線程CustomThread起動(dòng),但沒有馬上結(jié)束,因?yàn)檎{(diào)用t1.join();,所以要等到t1結(jié)束了,此線程才能向下執(zhí)行。

    [CustomThread1] Thread loop at 2//線程CustomThread1繼續(xù)執(zhí)行

    [CustomThread1] Thread loop at 3//線程CustomThread1繼續(xù)執(zhí)行

    [CustomThread1] Thread loop at 4//線程CustomThread1繼續(xù)執(zhí)行

    [CustomThread1] Thread end. //線程CustomThread1結(jié)束了

    [CustomThread] Thread end. // 線程CustomThread在t1.join();阻塞處起動(dòng),向下繼續(xù)執(zhí)行的結(jié)果

     

     

    五、從源碼看join()方法

     

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

     

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

    然后進(jìn)入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) //參數(shù)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{//進(jìn)入這個(gè)分支   
    18    while (isAlive()) {//判斷本線程是否為活動(dòng)的。這里的本線程就是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   }
     

     

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

    ----2009年02月12日

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

    評(píng)論

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

    主線程生成并起動(dòng)了子線程,而子線程里要進(jìn)行大量的耗時(shí)的運(yùn)算(這里可以借鑒下線程的作用),當(dāng)主線程處理完其他的事務(wù)后,需要用到子線程的處理結(jié)果,這個(gè)時(shí)候就要用到j(luò)oin();方法了。

    ????????????????????
    感覺這段很成問題  回復(fù)  更多評(píng)論
      

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

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

    上面這段代碼,不會(huì)異常啊。  回復(fù)  更多評(píng)論
      

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

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

    # re: 淺析 Java Thread.join() 2013-07-25 14:44 emmet7life
    @minelibra
    這個(gè)解釋不錯(cuò)喲  回復(fù)  更多評(píng)論
      

    # re: 淺析 Java Thread.join()[未登錄] 2013-09-12 07:08 Mark
    這個(gè)簡(jiǎn)單的東西,你搞那么復(fù)雜。主線程等待調(diào)用join方法的子線程執(zhí)行結(jié)束后再繼續(xù)執(zhí)行  回復(fù)  更多評(píng)論
      

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

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

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

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

    # re: 淺析 Java Thread.join() 2014-06-17 14:35 頭很大
    @YY
    這..... 這個(gè)知識(shí)點(diǎn) 我懂了  回復(fù)  更多評(píng)論
      

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

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

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

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

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

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


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


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 99久久婷婷国产综合亚洲| 亚洲成人黄色在线| 亚洲国产高清视频| 在线免费观看亚洲| 亚洲综合色婷婷在线观看| 国产成人精品亚洲| a级毛片免费高清毛片视频| 99久久国产免费中文无字幕| 18禁成年无码免费网站无遮挡| 免费人成年激情视频在线观看 | 亚洲综合精品网站在线观看| 久久久久久久尹人综合网亚洲| 亚洲欧洲视频在线观看| 在线观看亚洲电影| 日本人成在线视频免费播放| 最近最新中文字幕完整版免费高清| 免费一级毛片在线播放| 亚洲日本中文字幕区| 国产成人精品亚洲| 午夜影院免费观看| 国产乱子伦片免费观看中字| 亚洲av无码潮喷在线观看| 亚洲AV色欲色欲WWW| 三年片在线观看免费观看大全动漫 | 美女免费视频一区二区| 另类免费视频一区二区在线观看| 免费无码精品黄AV电影| 亚洲啪啪AV无码片| 久久久久亚洲国产| 久久成人免费播放网站| 免费国产精品视频| 亚洲精品中文字幕无码AV| 成年大片免费视频播放一级| 亚洲一区二区三区免费观看| 亚洲午夜爱爱香蕉片| 亚洲午夜理论片在线观看| a级毛片在线视频免费观看| 精品剧情v国产在免费线观看| 亚洲va无码专区国产乱码| mm1313亚洲国产精品无码试看 | 亚洲最大免费视频网|