前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >面试系列之-线程屏障cyclicBarrier(JAVA基础)

面试系列之-线程屏障cyclicBarrier(JAVA基础)

作者头像
用户4283147
发布2023-08-21 20:17:10
1540
发布2023-08-21 20:17:10
举报
文章被收录于专栏:对线JAVA面试对线JAVA面试

概述

是一个同步辅助类,允许一组线程相互等待,直到到达某个公共的屏障点,通过它可以完成多个线程之间相互等待,只有当每个线程都准备就绪后,才能各自继续往下执行后面的操作。

与CountDownLatch有相似的地方,都是使用计数器实现,当某个线程调用了CyclicBarrier的await()方法后,该线程就进入了等待状态,而且计数器执行加1操作,当计数器的值达到了设置的初始值,调用await()方法进入等待状态的线程会被唤醒,继续执行各自后续的操作。CyclicBarrier在释放等待线程后可以重用,所以,CyclicBarrier又被称为循环屏障。

使用场景

可以用于多线程计算数据,最后合并计算结果的场景;

CyclicBarrier与CountDownLatch的区别

CountDownLatch的计数器只能使用一次,而CyclicBarrier的计数器可以使用reset()方法进行重置,并且可以循环使用,CountDownLatch主要实现1个或n个线程需要等待其他线程完成某项操作之后,才能继续往下执行,描述的是1个或n个线程等待其他线程的关系。而CyclicBarrier主要实现了多个线程之间相互等待,直到所有的线程都满足了条件之后,才能继续执行后续的操作,描述的是各个线程内部相互等待的关系;

CyclicBarrier能够处理更复杂的场景,如果计算发生错误,可以重置计数器让线程重新执行一次;

CyclicBarrier中提供了很多有用的方法,比如:可以通过getNumberWaiting()方法获取阻塞的线程数量,通过isBroken()方法判断阻塞的线程是否被中断;

代码示例

示例代码如下:

代码语言:javascript
复制
public class CyclicBarrierExample {
  private static CyclicBarrier cyclicBarrier = new CyclicBarrier(5);
  public static void main(String[] args) throws Exception {
    ExecutorService executorService = Executors.newCachedThreadPool();
    for (int i = 0; i < 10; i++){
      final int threadNum = i;
      Thread.sleep(1000);
      executorService.execute(() -> {
        try {
          race(threadNum);
       } catch (Exception e) {
          e.printStackTrace();
       }
     });
   }
executorService.shutdown();
 }
  private static void race(int threadNum) throws Exception{
    Thread.sleep(1000);
    log.info("{} is ready", threadNum);
    cyclicBarrier.await();
    log.info("{} continue", threadNum);
 }
}

设置等待超时示例代码如下:

代码语言:javascript
复制
public class CyclicBarrierExample {
  private static CyclicBarrier cyclicBarrier = new CyclicBarrier(5);
  public static void main(String[] args) throws Exception {
    ExecutorService executorService = Executors.newCachedThreadPool();
    for (int i = 0; i < 10; i++){
      final int threadNum = i;
      Thread.sleep(1000);
      executorService.execute(() -> {
        try {
          race(threadNum);
       } catch (Exception e) {
          e.printStackTrace();
       }
     });
   }
    executorService.shutdown();
 }
  private static void race(int threadNum) throws Exception{
    Thread.sleep(1000);
    log.info("{} is ready", threadNum);
    try{
      cyclicBarrier.await(2000, TimeUnit.MILLISECONDS);
   }catch (BrokenBarrierException | TimeoutException e){
      log.warn("BarrierException", e);
   }
    log.info("{} continue", threadNum);
 }
}

在声明CyclicBarrier的时候,还可以指定一个Runnable,当线程达到屏障的时候,可以优先执行Runnable中的方法。示例代码如下:

代码语言:javascript
复制
public class CyclicBarrierExample {
  private static CyclicBarrier cyclicBarrier = new CyclicBarrier(5, () -> {
    log.info("callback is running");
 });
  public static void main(String[] args) throws Exception {
    ExecutorService executorService = Executors.newCachedThreadPool();
    for (int i = 0; i < 10; i++){
      final int threadNum = i;
      Thread.sleep(1000);
      executorService.execute(() -> {
        try {
          race(threadNum);
       } catch (Exception e) {
          e.printStackTrace();
       }
     });
   }
    executorService.shutdown();
 }
  private static void race(int threadNum) throws Exception{
    Thread.sleep(1000);
    log.info("{} is ready", threadNum);
    cyclicBarrier.await();
    log.info("{} continue", threadNum);
 }
}

cyclicBarrier实现原理

代码语言:javascript
复制
private final ReentrantLock lock = new ReentrantLock();
private final Condition trip = lock.newCondition();
//表示处在等待状态的线程个数
private int count;
//构造函数
public CyclicBarrier(int parties, Runnable barrierAction) {
  if (parties <= 0) throw new IllegalArgumentException();
    this.parties = parties;
    this.count = parties;
    this.barrierCommand = barrierAction;
}

CyclicBarrier主要借助重入锁ReentrantLock和Condition实现,count初始值等于CyclicBarrier实例化指明的等待线程数量,用于等待线程计数,parties表示有多少个个体(相当于调多少次await方法,每调一次await方法相当于一个线程到达了栅栏处),barrierAction其实相当于回调函数,当最后一个线程达到了栅栏处就会触发这个回调函数;

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

本文分享自 对线JAVA面试 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • cyclicBarrier实现原理
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com