不同工具对比
CyclicBarrier vs CountdownLatch:CyclicBarrier可以通过reset()实现重置门限值,CountDownLatch为一次性。
一、CountDownLatch
注意:new CountDownLatch(5)中数字必须严格跟期望等待数字保持一致,否则可能出现意外的结果(因为超出5的线程会不被进行等待)
1、代码使用样例
通过CountDownLatch实现:"主线程"等待"5个子线程"全部都完成"指定的工作(休眠1000ms)"之后,再继续运行。

1 import java.util.concurrent.CountDownLatch; 2 3 public class CountDownLatchTest { 4 5 private static CountDownLatch latch = new CountDownLatch(5); 6 7 public static void main(String[] args) { 8 9 System.out.println("Main Thread start...."); 10 System.out.println(); 11 12 for (int i = 0; i < 5; i++) { 13 new InnerThread().start(); 14 } 15 16 try { 17 latch.await(); 18 System.out.println(); 19 System.out.println("Main Thread latch.getCount = " + latch.getCount()); 20 } catch (InterruptedException e) { 21 System.out.println("Exception happened in latch await: " + e); 22 } 23 24 System.out.println("Main Thread end...."); 25 } 26 27 static class InnerThread extends Thread { 28 public void run() { 29 synchronized (InnerThread.class) { 30 try { 31 Thread.sleep(1000); 32 System.out.println(Thread.currentThread().getName() + " sleep 1000 ms."); 33 // 将CountDownLatch的数值减1 34 latch.countDown(); 35 System.out.println(Thread.currentThread().getName() + " count number: " + latch.getCount()); 36 } catch (InterruptedException e) { 37 e.printStackTrace(); 38 } 39 } 40 } 41 } 42 }
执行结果: 主线程等待,直至 latch 通过 countDown 减为0后,主线程才继续执行。

1 Main Thread start.... 2 3 Thread-1 sleep 1000 ms. 4 Thread-1 count number: 4 5 Thread-4 sleep 1000 ms. 6 Thread-4 count number: 3 7 Thread-0 sleep 1000 ms. 8 Thread-0 count number: 2 9 Thread-3 sleep 1000 ms. 10 Thread-3 count number: 1 11 Thread-2 sleep 1000 ms. 12 Thread-2 count number: 0 13 14 Main Thread latch.getCount = 0 15 Main Thread end....
2、常用方法解读
CountDownLatch(int count) // 构造一个用给定计数初始化的 CountDownLatch。 // 使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断。 void await() // 调用sync.acquireSharedInterruptibly(1)实现AQS中state=1 // 使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断或超出了指定的等待时间。 boolean await(long timeout, TimeUnit unit) // 递减锁存器的计数,如果计数到达零,则释放所有等待的线程。 void countDown() // 调用sync.releaseShared(1) 实现AQS中state-1 long getCount() // 返回当前计数。