CountDownLatch、CyclicBarrier 均可以用於: 在多線程異步執行過程當中,執行預約的流程後喚醒 指定的線程 進行相應的操做.
區別:
1,CountDownLatch 喚醒過一次,就廢棄了;CyclicBarrier能夠重複以前的預約流程,反覆喚醒。
2,CountDownLatch 可用於喚醒主線程,異步線程[任意線程,只要有他的實例];CyclicBarrier只能用於喚醒異步線程[貌似]。
3,CountDownLatch 喚醒指定線程後,當前線程並不阻塞;CyclicBarrier 喚醒指定線程後,當前線程會阻塞,等指定線程執行完成後,當前線程才繼續執行。
應用場景:
CountDownLatch:異步轉同步,,,
CyclicBarrier:批量多線程彙總,像短期跑批類的,
總結:
CyclicBarrier我是用的比較少,大部分場景都是用CountDownLatch就能夠了。java
package test; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CountDownLatch; import java.util.concurrent.CyclicBarrier; /** * CountDownLatch、CyclicBarrier 均可以用於: 在多線程異步執行過程當中,執行預約的流程後喚醒 指定的線程 進行相應的操做.<br> * * 區別:<br> * 1,CountDownLatch 喚醒過一次,就廢棄了;CyclicBarrier能夠重複以前的預約流程,反覆喚醒。<br> * 2,CountDownLatch 可用於喚醒主線程,異步線程[任意線程,只要有他的實例];CyclicBarrier只能用於喚醒異步線程[貌似]。<br> * 3,CountDownLatch 喚醒指定線程後,當前線程並不阻塞;CyclicBarrier喚醒指定線程後,當前線程會阻塞,等指定線程執行完成後,當前線程才繼續執行。<br> * * 應用場景:<br> * CountDownLatch:異步轉同步,,,<br> * CyclicBarrier:批量多線程彙總,像短期跑批類的,<br> * * 總結:<br> * CyclicBarrier我是用的比較少,大部分場景都是用CountDownLatch就能夠了。 * * @author Yuanqy * */ public class TestLatch { @org.junit.Test public void test() throws InterruptedException { // ==CountDownLatch=================================== try { final CountDownLatch latch = new CountDownLatch(5); long i = latch.getCount(); for (int j = 0; j < i; j++) { new Thread() { @Override public void run() { System.out.println("CountDownLatch:" + latch.getCount() + "\t" + this.getName());//線程存在併發 latch.countDown();// 計數遞減,當==0時 喚醒等待線程。 } }.start();// 異步執行 } latch.await();// 阻塞,直到latch.getCount()==0時喚醒 System.out.println("===Main1 is finish==="); } catch (InterruptedException e) { e.printStackTrace(); } // ==CyclicBarrier=================================== final CyclicBarrier cb = new CyclicBarrier(5, new Thread() { @Override public void run() { System.out.println("===Last is finish===");//到達指定次數喚醒 } }); for (int i = 0; i < cb.getParties(); i++) { new Thread("Thread_" + i) { @Override public void run() { try { for (int x = 0; x < 2; x++) {// 我是能夠重複使用的哦。 // cb.getNumberWaiting()返回已被await()的線程數量,不能用於計數。 Thread.sleep(500); System.out.println("CyclicBarrier:" + cb.getNumberWaiting() + "\t" + this.getName()); cb.await();// 阻塞當前線程, 喚醒CyclicBarrier 預約的線程先執行,當前線程等待 System.out.println("Please watch me!\t" + this.getName()); } } catch (InterruptedException | BrokenBarrierException e) { e.printStackTrace(); } } }.start();// 異步執行 } System.out.println("===Main2 is finish===");//這裏不阻塞 Thread.currentThread().join(); } }
測試結果:多線程
CountDownLatch:5 Thread-0 CountDownLatch:5 Thread-1 CountDownLatch:3 Thread-2 CountDownLatch:2 Thread-3 CountDownLatch:1 Thread-4 ===Main1 is finish=== ===Main2 is finish=== CyclicBarrier:0 Thread_2 CyclicBarrier:0 Thread_0 CyclicBarrier:0 Thread_1 CyclicBarrier:3 Thread_3 CyclicBarrier:4 Thread_4 ===Last is finish=== Please watch me! Thread_4 Please watch me! Thread_0 Please watch me! Thread_1 Please watch me! Thread_2 Please watch me! Thread_3 CyclicBarrier:0 Thread_0 CyclicBarrier:0 Thread_1 CyclicBarrier:0 Thread_4 CyclicBarrier:3 Thread_2 CyclicBarrier:4 Thread_3 ===Last is finish=== Please watch me! Thread_3 Please watch me! Thread_2 Please watch me! Thread_4 Please watch me! Thread_1 Please watch me! Thread_0