Java多線程--讓主線程等待所有子線程執行完畢 join

來源:互聯網
上載者:User

標籤:

首先從公司一道筆試題開始

 1 package test; 2  3 public class Test implements Runnable { 4  5     public int i = 0; 6  7     @Override 8     public void run() { 9         try {10             Thread.sleep(1000);11         } catch (InterruptedException e) {12             // TODO Auto-generated catch block13             e.printStackTrace();14         }15         i = 10;16     }17 18     public static void main(String[] args) {19         try {20             Test t = new Test();21             Thread th = new Thread(t);22             th.start();23             th.join();24             System.out.println(t.i);25         } catch (Exception ex) {26 27         }28 29     }30 }

 問23行代碼怎麼寫,才能讓24行列印出10?

不少筆試者會選t.wait()或者th.wait()!

面試的時候問他為什麼,他具體也說不清楚,感覺就是見過這個wait方法,但是wait方法的含義確一知半解。

wait 是什麼意思呢?我舉例子啊,比如我想讓本線程放棄當前對象鎖,說直白點就是讓別的對象進入同步塊

 1 package test; 2  3 public class Test implements Runnable { 4  5     public Object i = new Object(); 6  7     @Override 8     public void run() { 9         synchronized (i) {10             System.out.println(Thread.currentThread().getName()+"enter ");11 //            i.notify();12             try {13                 i.wait();14             } catch (InterruptedException e) {15                 // TODO Auto-generated catch block16                 e.printStackTrace();17             }18             System.out.println(Thread.currentThread().getName()+"out ");19         }20     }21 22     public static void main(String[] args) {23         try {24             Test t = new Test();25             Thread th1 = new Thread(t);26             Thread th2 = new Thread(t);27             th1.start();28             th2.start();29             30             31         } catch (Exception ex) {32 33         }34 35     }36 }

如上例,你會看到輸出

Thread-0enter
Thread-1enter

不會看到

Thread-1out
Thread-0out

因為Thread-0 先獲得了Object i 鎖,然後運行到13行,釋放了該鎖,

這個時候Thread-1就獲得了Object i 鎖,進入了同步代碼塊,然後同樣運行13行,也釋放了該鎖。

這個時候在有兩個線程Thread-0和Thread-1等待獲得Object i 鎖,由於代碼中沒有調用i.notifyAll(),所以這個程式永遠不會退出。

但是如果開啟注釋11行,那麼你將會看到結果

Thread-0enter
Thread-1enter
Thread-0out

 

因為Thread-0 先獲得了Object i 鎖,然後運行到13行,釋放了該鎖,

這個時候Thread-1就獲得了Object i 鎖,進入了同步代碼塊,運行到11行,i.notify(),

那麼這個意思就是說別的等待i鎖的線程可以喚醒了,一旦我(Thread-1)釋放鎖(13行調用wait()),那麼Thread-0就可以獲得i鎖繼續執行了。

此程式中沒有在Thread-1 釋放i鎖(wait())之後notify,所以永遠不會看到Thread-1out

 

再回到這個題目,我們的意思是讓主線程等待所有子線程執行完畢 ,再執行。更何況筆試題中沒有鎖對象。更別提wait()了。

所以,此處應該用th.join();   Thread.join()方法會阻塞主線程繼續向下執行。

 1 public class TestThread extends Thread   2 {   3     private CountDownLatch countDownLatch;   4            5     public TestThread(CountDownLatch countDownLatch)   6     {   7         this.countDownLatch = countDownLatch;   8     }   9 10     public void run()  11     {  12         System.out.println(this.getName() + "子線程開始");  13         try  14         {  15             // 子線程休眠五秒  16             Thread.sleep(5000);  17         }  18         catch (InterruptedException e)  19         {  20             e.printStackTrace();  21         }22 23         System.out.println(this.getName() + "子線程結束");24           25         // 倒數器減126         countDownLatch.countDown();27     }28 }
 1 public class Main 2 { 3     public static void main(String[] args) 4     { 5         long start = System.currentTimeMillis(); 6          7         // 建立一個初始值為5的倒數計數器 8         CountDownLatch countDownLatch = new CountDownLatch(5); 9         for(int i = 0; i < 5; i++)10         {11             Thread thread = new TestThread(countDownLatch);12             thread.start();13         }14         15         try16         {17             // 阻塞當前線程,直到倒數計數器倒數到018             countDownLatch.await();19         }20         catch (InterruptedException e)21         {22             e.printStackTrace();23         }24         25         long end = System.currentTimeMillis();26         System.out.println("子線程執行時間長度:" + (end - start));27     }28 }

 

Java多線程--讓主線程等待所有子線程執行完畢 join

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.