CountDownLatch
    主要方法 countdown 和await
    作用:有两种
    1、开启多个分线程,都执行完了再执行主线程
    思路:主线程建一个CountDownLatch ,分线程里作为参数把它传入,当分线程运行完其工作后countdown,
    主线程就一直await,等所有分线程都countdown之后主线程再执行。
    2、同时启动多个线程
    思路:主线程建一个CountDownLatch(1),把其作为参数传入各个分线程,分线程第一行代码就执行await()
    于是所有分线程都同时卡住了。然后主线程在适当时间 countdown一下,分线程便开始同时工作了,这样可以最大程度提高并行性。

    CyclicBarrier
    感觉这个方法使用场景不多呀!
    从字面上的意思可以知道,这个类的中文意思是“循环栅栏”。大概的意思就是一个可循环利用的屏障。
    它的作用就是会让所有线程都等待完成后才会继续下一步行动。
    举个例子,就像生活中我们会约朋友们到某个餐厅一起吃饭,有些朋友可能会早到,有些朋友可能会晚到,但是这个餐厅规定必须等到所有人到齐之后才会让我们进去。
    这里的朋友们就是各个线程,餐厅就是 CyclicBarrier

    public CyclicBarrier(int parties)
    public CyclicBarrier(int parties, Runnable barrierAction)
    主要方法就一个await()

    解析:
    parties 是参与线程的个数
    第二个构造方法有一个 Runnable 参数,这个参数的意思是最后一个到达线程要做的任务
    具体例子如下 https://www.jianshu.com/p/333fd8faa56e

    CyclicBarrier 与 CountDownLatch 区别
    CountDownLatch 是一次性的,CyclicBarrier 是可循环利用的,从跨栏demo可以看出来。
    CountDownLatch 参与的线程的职责是不一样的,有的在倒计时,有的在等待倒计时结束。CyclicBarrier 参与的线程职责是一样的。

    CyclicBarrier支持重置状态,达到循环利用的目的。这也是Cyclic的由来。CyclicBarrier中有一个内部类Generation,代表当前的同步处于哪一个阶段。
    当最后一个任务完成,执行任务的线程会通过nextGeneration方法来重置Generation。也可以通过CyclicBarrier的reset方法来重置Generation。