通過Thread.join()和CountDownLatch來實現進程同步

來源:互聯網
上載者:User

1.Thread.join()

如果在一個進程,如main中調用另一個thread的join()函數會導致main函數阻塞,直至thread執行完畢。

public class JoinTest {public static void main(String[] args) {System.out.println("main starts.");Thread thread = new Thread(new Runnable() {public void run() {for(int i = 0;i < 5;i++){try {System.out.println("thread" + i + " starts.");Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}}}});thread.start();try {thread.join();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("main ends.");}}

輸出結果為:

main starts.thread0 starts.thread1 starts.thread2 starts.thread3 starts.thread4 starts.main ends.

從輸出結果來看,main線程列印了main starts,執行到thread.join()被阻塞了,此時子線程開始列印log,且列印間隔為500ms,當子線程執行完畢後,main線程列印輸出main ends。

如果我們將thread.join()改成thread.join(1500),那麼輸出結果如下:

main starts.thread0 starts.thread1 starts.thread2 starts.main ends.thread3 starts.thread4 starts.

這裡採用的是join的一個重載方法,join(long millis),表示等到線程thread執行完畢或者阻塞millis時間後才能允許調用這個函數的線程繼續執行下去。從上述輸出中我們可以看出main線程並沒有等待thread執行完畢,而是等待了1500ms就繼續執行了。

其實,這裡還可以用這種方法來實現main線程等待thread線程:

//try {//thread.join();//} catch (InterruptedException e) {//e.printStackTrace();//}while(thread.isAlive()){try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}

判斷thread是否處於alive狀態,如果是那麼main線程休眠100ms,如果thread結束了,main再繼續執行。

2.CountDownLatch

CountDownLatch中維護了一個計數器,初始化時接受一個整型值作為計數器初始值,其中包括兩個函數await和countDown,當在某個函數中調用await時,該線程被阻塞,沒調用一次countDown計數器值減一,只有當計數器的值為0的時候剛才被阻塞的線程才能繼續向下執行。

public class CountDownLatchTest {public static void main(String[] args) throws InterruptedException {final CountDownLatch startCdt = new CountDownLatch(5);final CountDownLatch endCdt = new CountDownLatch(5);for(int i = 0; i < 5; i++){new Thread(new Runnable(){public void run() {System.out.println(Thread.currentThread().getName() + "starts.");try {startCdt.countDown();startCdt.await();//建立的5個線程都在等startCdt的count=0才繼續往下執行} catch (InterruptedException e) {e.printStackTrace();}finally{endCdt.countDown();//每個線程執行完後都將count值減1System.out.println(Thread.currentThread().getName() + " ends.");}}}).start();}endCdt.await();//main線程當endCdt的值為0時才繼續執行,也就是等上邊建立的5個線程執行完畢後才繼續執行System.out.println("all threads end.");}


執行結果如下:

Thread-1starts.Thread-3starts.Thread-4starts.Thread-2starts.Thread-0starts.Thread-0 ends.Thread-1 ends.Thread-3 ends.Thread-4 ends.Thread-2 ends.all threads end.

儘管每個子線程建立後立刻執行,但是當他們在運行到startCdt.await()時都被阻塞了,只有startCdt的計數器的值減為0時才繼續向下執行;同理main線程在執行到endCdt.await()時阻塞,只有當其計數器減為0時才繼續執行。如果沒有endCdt.await(),那麼執行結果如下:

Thread-1starts.Thread-4starts.Thread-0starts.all threads end.Thread-2starts.Thread-3starts.Thread-3 ends.Thread-1 ends.Thread-4 ends.Thread-0 ends.Thread-2 ends.









相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.