CountDownLatch与CyclicBarrier的介绍与使用

1.CountDownLatch介绍与使用
2.CyclicBarrier的介绍与使用
3.CountDownLatch与CyclicBarrier的区别



CountDownLatch与CyclicBarrier都是jdk并发包里提供的常用工具类,这里只介绍和使用场景。至于想查着两个工具类用法的同学们可能更想了解计算机底层的并发发生的原因,想要更深入的了解,更好的处理并发和编程中可能出现的并发。我在这里推荐两本书《深入了解计算机系统》和《java并发编程的艺术》


1.CountDownLatch介绍与使用
CountDownLatch等待多线程完成,允许一个或者多个线程等待其它线程完成操作之后再执行(阻塞/通知机制)。
假设我们有这样一个场景:需要解析excel里面的多条sheet数据,此时考虑使用多线程,每个线程解析一条sheet数据,等到所有的sheet都解析完之后,程序需要提示解析完成。在这个场景中,主线程要等待所有的执行sheet处理的线程都执行完之后才能算完成。
解决上面的场景可以使用join()的方法,主线程阻塞出让执行的时间,等其它的线程执行完之后再执行。
CountDownLatch也可以实现join()的功能,并且比join()的功能更多。
演示代码:

public class CountDownLatchTest {

    static CountDownLatch latchTest = new CountDownLatch(2);

    public static void main(String[] args) throws Exception {

        for (int i = 0 ;i<2 ; i++){
            new Runnable(){
                @Override
                public void run() {
                    System.out.println("hello java");
                    latchTest.countDown();
                }
            }.run();
        }
        latchTest.await();
        System.out.println("hello c++");
    }

}

CountDownLatch对象在构造的时候需要传入int类型的参数作为计数器N,当调用countDown方法的时候N就会减1,await方法会阻塞调用该方法的线程,直到N位0,才会执行被阻塞的线线程,当N永远不会为1的时候,调用wait方法的线程就会一直被阻塞,可以使用awit(long time,TimeUnit unit)方法,超过设定的时间,就不会阻塞该线程了。


2.CyclicBarrier的介绍与使用
CyclicBarrier可循环使用的屏障,CyclicBarrier可以设定一定数量,并使调用该类的实现类的wait方法的线程处于阻塞状态,当调用wait方法的数量等于设定的数量,阻塞的线程会被notify并执行。
CyclicBarrier有一个可以灵活使用在构造函数CyclicBarrier(int partis,Runnable action),意思是当阻塞线程达到指定的数量的时候,优先调用action线程。
演示代码:

public class TestCyclicBarrierBannerFlow implements Runnable{

    private int abs = 4;

    private CyclicBarrier cyclicBarrier = new CyclicBarrier(abs,this);

    private Executor executor = Executors.newFixedThreadPool(abs);

    private ConcurrentHashMap sheetBankWaterCount = new ConcurrentHashMap();

    private void count(){

        while (abs>0){
            --abs;
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    sheetBankWaterCount.put(Thread.currentThread().getName(),2);
                    try {
                        cyclicBarrier.await();
                    }catch (InterruptedException | BrokenBarrierException e){
                        e.printStackTrace();
                    }
                }
            });

        }

    }

    @Override
    public void run() {

        int result = 0;
        for (Map.Entry entry:sheetBankWaterCount.entrySet()) {
            result+=entry.getValue();
        }
        System.out.println(result);
    }

    public static void main(String[] args) {
        TestCyclicBarrierBannerFlow flow = new TestCyclicBarrierBannerFlow();
        flow.count();
    }
}

3.CountDownLatch与CyclicBarrier的区别
CountDownLatch的计数器只能使用一次,而CyclicBarrier的计数器可以使用reset方法重置,所以CyclicBarrier可以更灵活的在业务场景中使用。
CyclicBarrier还可以根据getNumberWaiting方法获取CyclicBarrier阻塞线程的数量,isBroken()可以判断阻塞线程是否被中断。

你可能感兴趣的:(并发编程)