CountDownLatch实现原理

    • 底层基于 AbstractQueuedSynchronizer 实现,CountDownLatch 构造函数中指定的count直接赋给AQS的state;
    • 每次countDown()则都是release(1)减1,最后减到0时,unpark阻塞线程;唤醒操作由最后一个执行countdown方法的线程执行的。
    • 调用await()方法时,当前线程就会判断state属性是否为0。
      • 如果为0,则继续往下执行,并唤醒之前调用await方法,阻塞的线程。
      • 如果不为0,则阻塞当前线程,直到某个线程将state属性置为0。

    CountDownLatch与Thread.join的区别

    • CountDownLatch的作用就是允许一个或多个线程等待其他线程完成操作,看起来有点类似join() 方法,但其提供了比 join() 更加灵活的API。
    • CountDownLatch可以手动控制在n个线程里调用n次countDown()方法使计数器进行减一操作,也可以在一个线程里调用n次执行减一操作。
    • join() 的实现原理是不停检查join线程是否存活,如果 join 线程存活则让当前线程永远等待。所以两者之间相对来说还是CountDownLatch使用起来较为灵活。

    CountDownLatch与CyclicBarrier的区别
    CountDownLatch和CyclicBarrier都能够实现线程之间的等待,只不过它们侧重点不同:

    1. CountDownLatch的计数器只能使用一次,而CyclicBarrier的计数器可以使用reset() 方法重置。所以CyclicBarrier能处理更为复杂的业务场景,比如如果计算发生错误,可以重置计数器,并让线程们重新执行一次
    2. CyclicBarrier还提供getNumberWaiting(可以获得CyclicBarrier阻塞的线程数量)、isBroken(用来知道阻塞的线程是否被中断)等方法。
    3. CountDownLatch会阻塞主线程,CyclicBarrier不会阻塞主线程,只会阻塞子线程。
    4. CountDownLatch和CyclicBarrier都能够实现线程之间的等待,只不过它们侧重点不同。CountDownLatch一般用于一个或多个线程,等待其他线程执行完任务后,再执行。CyclicBarrier一般用于一组线程互相等待至某个状态,然后这一组线程再同时执行。
    5. CyclicBarrier 还可以提供一个 barrierAction,合并多线程计算结果。
    6. CyclicBarrier是通过ReentrantLock的”独占锁”和Conditon来实现一组线程的阻塞唤醒的,而CountDownLatch则是通过AQS的“共享锁”实现