CountDownLatch与CyclicBarrier

CountDownLatch

CountDownLatch这个类使一个线程等待其他线程完成各自的工作再执行,例如主线程希望子线程完成操作后让自线程使用。
CountDownLatch是通过计数器实现,每次完成一个任务后,计数器减一当为0时,CountDownLatch.await()方法的线程就可以恢复执行任务。


图片 5.png

如图我们Tw1线程Tw2线程 执行了await方法 进行等待,这是countDownlotch设置为5,ta、tb、tc、td调用countDown方法让计数器减一,当计数器为0时,Tw1、Tw2线程恢复运行。

注意:不是子countdownlatch不是线程的数量、而且当countdownchlatch不等于线程数
public class UseCountDownLatch {

   static CountDownLatch latch = new CountDownLatch(4);

    private static class InitThread implements Runnable{

        public void run() {
            System.out.println("Thread_"+Thread.currentThread().getId()
                    +" ready init work......");
            latch.countDown();
          
        }
    }
    
  public static void main(String[] args) throws InterruptedException {
     
        new Thread(new BusiThread()).start();
        for(int i=0;i<=3;i++){
            Thread thread = new Thread(new InitThread());
            thread.start();
        }

        latch.await();
        System.out.println("Main do ites work........");
    }
}

demo中演示的是一段 开启四个子线程,主线程调用await进入阻塞状态,调用countDown方法,当countdownchlatch为0时,主线程阻塞状态恢复。

CyclicBarrier

CyclicBarrier是一种线程间的屏障,一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续运行。
CyclicBarrier默认的构造方法是CyclicBarrier(int parties),其参数表示屏障拦截的线程数量,每个线程调用await方法告诉CyclicBarrier我已经到达了屏障,然后当前线程被阻塞。
CyclicBarrier还提供一个更高级的构造函数CyclicBarrier(int parties,Runnable barrierAction),用于在线程到达屏障时,优先执行barrierAction,方便处理更复杂的业务场景。

}S3V32`PS)TZFW%1SXYLGCF.png

public class UseCyclicBarrier {

    private static CyclicBarrier barrier
            = new CyclicBarrier(4,new CollectThread());


    public static void main(String[] args) {
        for(int i=0;i<4;i++){
            Thread thread = new Thread(new SubThread());
            thread.start();
        }

    }

    /*汇总的任务*/
    private static class CollectThread implements Runnable{

        @Override
        public void run() {
            System.out.println("do other business........");
        }
    }

    /*相互等待的子线程*/
    private static class SubThread implements Runnable{

        @Override
        public void run() {
            long id = Thread.currentThread().getId();
            resultMap.put(Thread.currentThread().getId()+"",id);
            try {
                Thread.sleep(1000+id);
                System.out.println("Thread_"+id+" ....do something ");
                barrier.await();
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }
}

这里我们开启了4个子线程,他们全部完成工作后,汇总线程CollectThread执行。

两者区别

CountDownLatch的计数器只能使用一次,而CyclicBarrier的计数器可以反复使用。
CountDownLatch.await一般阻塞工作线程,所有的进行预备工作的线程执行countDown,而CyclicBarrier通过工作线程调用await从而自行阻塞,直到所有工作线程达到指定屏障,再大家一起往下走。
在控制多个线程同时运行上,CountDownLatch可以不限线程数量,而CyclicBarrier是固定线程数。
同时,CyclicBarrier还可以提供一个barrierAction,合并多线程计算结果。

你可能感兴趣的:(CountDownLatch与CyclicBarrier)