轉載請注明原文地址:http://www.cnblogs.com/ygj0930/p/6558349.html
一:CountDownLatch
CountDownLatch是一個執行 完成任務線程數 的 倒數計數器。我們考慮這種情況:士兵晨練,必須全隊士兵集合完畢才開始跑步。用程序描述就:在晨練線程中,逐個啟動士兵的集合線程,執行集合動作;等所有士兵的集合線程都執行完畢,才能繼續晨練線程執行跑步操作。那么我們怎么快速地統計已經集合的士兵線程數,以及怎樣在集合完畢后第一時間啟動跑步呢?這里就需要用到CountDownLatch。
1:首先,我們在晨練線程中創建一個CountDownLatch:static final CountDownLatch countDownLatch = new CountDownLatch(10);//構造參數說明有多少個需要完成的線程
2:在每個士兵的集合線程中,通過:countDownLatch.countDown(); //說明當前線程已經執行到屏障處,把倒數計數器值減1
3:在晨練線程中,通過:countDownLatch.await(); //暫時掛起線程,等待倒數計數器為0時自動喚醒,繼續執行
二:CyclicBarrier
與countDownLatch相反,這是一個加法計數器的同步屏障,並且可以重復使用。它在每個線程中設置屏障點,當一個線程執行到屏障點時就需要停下,計數器+1,直到計數器達到創建時指定值時執行相應的響應線程,並且全部線程繼續執行,直到下一個屏障處等待或者執行完畢。
1:創建CyclicBarrier同步屏障對象,設置屏障處計數值以及達到該值后執行什么響應動作線程:
CyclicBarrier barrier = new CyclicBarrier(n, new BarrierDone_Run());
2:在BarrierDone_Run線程中,定義 執行到屏障處而停頓的線程數達到設定值 時,啟動響應線程執行后續操作。
3:逐個啟動工作線程,在工作線程的run()方法中,通過: barrier.await(); //設定屏障,當線程執行到這步時掛起,直到計數器達到設定值時才繼續執行
三:比較
1:CountDownLatch是把主干線程掛起,在任務線程中進行倒數計數,直到任務線程執行完才喚醒主干線程繼續執行;
CyclicBarrier是把任務線程掛起,直到所有任務線程執行到屏障處再放行繼續執行;
2:CountDownLatch達到屏障放行標准后放行的是主干線程;
CyclicBarrier達到屏障放行標准后放行的是任務線程,並且還會額外地觸發一個達到標准后執行的響應線程;