博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
AQS同步组件--CyclicBarrier
阅读量:6706 次
发布时间:2019-06-25

本文共 4393 字,大约阅读时间需要 14 分钟。

CyclicBarrier

CyclicBarrier也是一个同步辅助类,它允许一组线程相互等待直到到达某个工作屏障点,通过他可以完成多线程之间的相互等待。每个线程都就绪之后才能执行后面的操作。和CountLatch有相似的地方都是通过计数器来实现的。当某个线程执行了await()方法后就进入等待状态,计数器进行加1操作,当增加后的值达到我们设定的值后,线程被唤醒,继续执行后续操作。CyclicBarrier是可重用的计数器,CyclicBarrier的使用场景和CountDownLatch的使用场景很相似,可以用于多线程计算数据最后总计结果。

CyclicBarrier和CountDownLatch的使用区别:

  1. CountDownLatch的计数器只能使用一次,CyclicBarrier可以用reset方法重置。
  2. CountDownLatch是一个线程等待其他线程完成某个操作后才能继续执行。也就是一个或个多线程等待其他的关系,而CyclicBarrier是实现了多个线程之间的相互等待,所有线程都满足了条件之后才能继续使用。

演示代码

@Slf4jpublic class CyclicBarrierExample1 {    private static CyclicBarrier barrier = new CyclicBarrier(5);    public static void main(String[] args) throws Exception {        ExecutorService executor = Executors.newCachedThreadPool();        for (int i = 0; i < 10; i++) {            final int threadNum = i;            Thread.sleep(1000);            executor.execute(() -> {                try {                    race(threadNum);                } catch (Exception e) {                    log.error("exception", e);                }            });        }        executor.shutdown();    }    private static void race(int threadNum) throws Exception {        Thread.sleep(1000);        log.info("{} is ready", threadNum);        barrier.await();        log.info("{} continue", threadNum);    }}复制代码

输出结果如下:

20:43:46.324 [pool-1-thread-1] INFO com.concurrency.example.aqs.CyclicBarrierExample1 - 0 is ready20:43:47.322 [pool-1-thread-2] INFO com.concurrency.example.aqs.CyclicBarrierExample1 - 1 is ready20:43:48.323 [pool-1-thread-3] INFO com.concurrency.example.aqs.CyclicBarrierExample1 - 2 is ready20:43:49.323 [pool-1-thread-4] INFO com.concurrency.example.aqs.CyclicBarrierExample1 - 3 is ready20:43:50.325 [pool-1-thread-5] INFO com.concurrency.example.aqs.CyclicBarrierExample1 - 4 is ready20:43:50.325 [pool-1-thread-5] INFO com.concurrency.example.aqs.CyclicBarrierExample1 - 4 continue20:43:50.325 [pool-1-thread-1] INFO com.concurrency.example.aqs.CyclicBarrierExample1 - 0 continue20:43:50.325 [pool-1-thread-2] INFO com.concurrency.example.aqs.CyclicBarrierExample1 - 1 continue20:43:50.325 [pool-1-thread-4] INFO com.concurrency.example.aqs.CyclicBarrierExample1 - 3 continue20:43:50.325 [pool-1-thread-3] INFO com.concurrency.example.aqs.CyclicBarrierExample1 - 2 continue20:43:51.325 [pool-1-thread-6] INFO com.concurrency.example.aqs.CyclicBarrierExample1 - 5 is ready20:43:52.326 [pool-1-thread-1] INFO com.concurrency.example.aqs.CyclicBarrierExample1 - 6 is ready20:43:53.326 [pool-1-thread-2] INFO com.concurrency.example.aqs.CyclicBarrierExample1 - 7 is ready20:43:54.326 [pool-1-thread-4] INFO com.concurrency.example.aqs.CyclicBarrierExample1 - 8 is ready20:43:55.327 [pool-1-thread-3] INFO com.concurrency.example.aqs.CyclicBarrierExample1 - 9 is ready20:43:55.327 [pool-1-thread-3] INFO com.concurrency.example.aqs.CyclicBarrierExample1 - 9 continue20:43:55.327 [pool-1-thread-6] INFO com.concurrency.example.aqs.CyclicBarrierExample1 - 5 continue20:43:55.327 [pool-1-thread-1] INFO com.concurrency.example.aqs.CyclicBarrierExample1 - 6 continue20:43:55.327 [pool-1-thread-2] INFO com.concurrency.example.aqs.CyclicBarrierExample1 - 7 continue20:43:55.327 [pool-1-thread-4] INFO com.concurrency.example.aqs.CyclicBarrierExample1 - 8 continue复制代码

我们定义了 private static CyclicBarrier barrier = new CyclicBarrier(5),每次调用await后加1 知道等于5就一起执行接下来的操作。

我们在创建CyclicBarrier的时候是可以传入一段runable的,下面看一下代码

@Slf4jpublic class CyclicBarrierExample3 {    private static CyclicBarrier barrier = new CyclicBarrier(5, () -> {        log.info("callback is running");    });    public static void main(String[] args) throws Exception {        ExecutorService executor = Executors.newCachedThreadPool();        for (int i = 0; i < 10; i++) {            final int threadNum = i;            Thread.sleep(1000);            executor.execute(() -> {                try {                    race(threadNum);                } catch (Exception e) {                    log.error("exception", e);                }            });        }        executor.shutdown();    }    private static void race(int threadNum) throws Exception {        Thread.sleep(1000);        log.info("{} is ready", threadNum);        barrier.await();        log.info("{} continue", threadNum);    }}复制代码

在线程到达=执行屏障时,线程会优先执行这个runable

private static CyclicBarrier barrier = new CyclicBarrier(5, () -> {        log.info("callback is running");    });复制代码

转载地址:http://dddlo.baihongyu.com/

你可能感兴趣的文章
[android]android下apk的安装过程
查看>>
Spring4.0支持Groovy配置
查看>>
MVC5 网站开发之四 业务逻辑层的架构和基本功能
查看>>
ffmpeg h265
查看>>
使用MFC::CArchive
查看>>
UVA - 10131Is Bigger Smarter?(DAG上的DP)
查看>>
jQuery----各版本
查看>>
js获取项目根路径
查看>>
shopex商城的部署和安装
查看>>
如何通俗易懂地解释遗传算法?有什么例子?
查看>>
java并发 使用ScheduledExecutor的温室控制器--thinking in java 21.7.5
查看>>
如何预测一个互联网产品的未来—一套关于产品的数学模型
查看>>
常见tcp端口
查看>>
C#开发微信门户及应用(36)--微信卡劵管理的封装操作
查看>>
[CareerCup] 17.12 Sum to Specific Value 和为特定数
查看>>
Entity Framework与ADO.Net及NHibernate的比较
查看>>
c++ 17介绍
查看>>
如何从Apache官网下载apache
查看>>
李洪强经典面试题26(选择题)
查看>>
【前台 乱码】 前台单独乱码+后台往前台传输的数据乱码
查看>>