首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >理解Java并发工具类CyclicBarrier

理解Java并发工具类CyclicBarrier

作者头像
我是攻城师
发布2018-09-30 11:34:01
5340
发布2018-09-30 11:34:01
举报

CyclicBarrier这个并发工具类和上篇文章中提到的CountDownLatch比较类似,可以把CyclicBarrier看做是可以可以复用的CountDownLatch。

CountDownLatch在Oracle官网文档中定义是,一组线程其他另外一组线程都执行完成之后,该组线程才可以同时进行工作。这和软件开发中协作非常类似,比如dev团队开发完成之后,qa团队才可以进行测试工作。qa团队是一组等待线程,dev团队是一组工作的线程,只有当dev全部完成之后,qa才开始进行测试。

CyclicBarrier在官网的定义是,一组线程中,必须相互等待其他的线程完成之后,他们才可以进入下一个协作项目反复如此。比如还是在软件开发中,一个项目来了,需要同时由后端团队和前端团队都开发完成之后才能提测,否则就相互等待,直到它们全部完成之后,才可以一起进入一个循环中。

我们来看一个非常简单的CyclicBarrier例子:

CyclicBarrier cyclicBarrier=new CyclicBarrier(2, new Runnable() {
            @Override
            public void run() {
                System.out.println("任务完成,触发一次.....");
            }
        });

       Runnable runnable=new Runnable() {
           @Override
           public void run() {
               try {
                   Thread.sleep(1000);
                   cyclicBarrier.await();
               } catch (InterruptedException e) {
                   e.printStackTrace();
               } catch (BrokenBarrierException e) {
                   e.printStackTrace();
               }
           }
       };


       new Thread(runnable).start();
       new Thread(runnable).start();

        new Thread(runnable).start();
        new Thread(runnable).start();

输出结果:

任务完成,触发一次.....
任务完成,触发一次.....

CountDownLatch和CyclicBarrier的不同之处在于:

(1)CountDownLatch仅仅可以使用一次而CyclicBarrier可以循环利用

(2)CountDownLatch类强调的是调用countDown方法的次数,而CyclicBarrier类强调的是至少有N个线程调用await方法。

(3)CyclicBarrier方法可以额外注册一个任务,在每轮循环执行await之后,会由最后一个调用await方法的线程,负责调用额外的任务。如上面的例子。

(4)CountDownLatch的底层使用的AQS的共享锁来实现的,而CyclicBarrier则是由ReentrantLock+Condition实现的相对来说更简单。

关于两者的功能区别,可以看下面两个伪代码:

CountDonwLatch:

public class CountDownLatch {
    private Object mutex = new Object();
    private int count;

    public CountDownLatch(int count) {
        this.count = count;
    }

    public void await() throws InterruptedException {
        synchronized (mutex) {
            while (count > 0) {
                mutex.wait();
            }
        }
    }

    public void countDown() {
        synchronized (mutex) {
            if (--count == 0)
                mutex.notifyAll();
        }

    }
}

CyclicBarrier:

public class CyclicBarrier {
    private Object mutex = new Object();
    private int count;

    public CyclicBarrier(int count) {
        this.count = count;
    }

    public void await() throws InterruptedException {
        synchronized (mutex) {
            count--;
            while(count > 0)
                mutex.wait();
            mutex.notifyAll();
        }
    }
}

总结:

本文主要了介绍了Java里面CyclicBarrier类功能以及它与CountDownLatch的区别和联系,最后并给出了实现他们的一些伪代码,两者的主要不同之处在于CyclicBarrier是可以多次复用的一个示例,只要指定的数量的线程调用await方法后,reset重置方法就会自动调用,不需要在代码中显式使用,这一点需要注意。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-08-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 我是攻城师 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档