JUC工具类CyclicBarrier

本文详细介绍了Java并发工具类CyclicBarrier的使用,包括其构造方法、核心方法如await()和reset(),以及与CountDownLatch的区别。通过运动员比赛的例子展示了CyclicBarrier如何确保所有参与者准备就绪后才开始。此外,还探讨了在选择CyclicBarrier或CountDownLatch时的考量因素。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CyclicBarrier是一个同步辅助类,允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier。

CyclicBarrier 提供的操作:

CyclicBarrier(int parties)
// 创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,但它不会在启动 barrier 时执行预定义的操作。
CyclicBarrier(int parties, Runnable barrierAction)
// 创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,并在启动 barrier 时执行给定的屏障操作,该操作由最后一个进入 barrier 的线程执行。
int await()
// 在所有参与者都已经在此 barrier 上调用 await 方法之前,将一直等待。
int await(long timeout, TimeUnit unit)
// 在所有参与者都已经在此屏障上调用 await 方法之前将一直等待,或者超出了指定的等待时间。
int getNumberWaiting()
// 返回当前在屏障处等待的参与者数目。
int getParties()
// 返回要求启动此 barrier 的参与者数目。
boolean isBroken()
// 查询此屏障是否处于损坏状态。
void reset()
// 将屏障重置为其初始状态。

案例:参见比赛的运动员都准备好了,比赛才能开始。

package com.lchtest.juc.assistant;

import java.util.Random;
import java.util.concurrent.*;

public class CyclicBarrierTest1 {
    public static void main(String[] args) {
        CyclicBarrier barrier = new CyclicBarrier(3, () ->{
            System.out.println("裁判打响了发令枪!");
        });
        ExecutorService executor = Executors.newFixedThreadPool(3);
        executor.execute(new Runner(barrier, "1号选手"));
        executor.execute(new Runner(barrier, "2号选手"));
        executor.execute(new Runner(barrier, "3号选手"));
        /*barrier.reset();
        executor.submit(new Runner(barrier, "4号选手"));
        executor.submit(new Runner(barrier, "5号选手"));
        executor.submit(new Runner(barrier, "6号选手"));*/
        executor.shutdown();
    }
}

class Runner implements Runnable{
    private CyclicBarrier barrier;
    private String name;
    public Runner(CyclicBarrier barrier, String name){
        this.barrier = barrier;
        this.name = name;
    }

    @Override
    public void run() {
        try {
            TimeUnit.SECONDS.sleep(new Random().nextInt(8));
            // barrier的await方法,在所有参与者都已经在此 barrier 上调用 await 方法之前,将一直等待
            System.out.println(name + "准备好了.");
            barrier.await();
        } catch (Exception e){
            e.printStackTrace();
        }
        System.out.println(name + " 起跑!");
    }
}

在这里插入图片描述
CyclicBarrier与CountDownLatch的区别
这两个类都可以实现一组线程在到达某个条件之前进行等待,它们内部都有一个计数器,当计数器的值不断的减为0的时候所有阻塞的线程将会被唤醒。

区别在于:

  • CyclicBarrier的计数器由自己控制,CountDownLatch的计数器则由使用者来控制
  • 在CyclicBarrier中线程调用await方法不仅会将自己阻塞还会将计数器减1,而在CountDownLatch中线程调用await方法只是将自己阻塞而不会减少计数器的值。
  • CountDownLatch只能拦截一轮,而CyclicBarrier可以实现循环拦截。一般来说用CyclicBarrier可以实现CountDownLatch的功能,而反之则不能。至于何时使用CyclicBarrier,何时使用CountDownLatch,看情况决定

源码分析: https://www.cnblogs.com/skywang12345/p/3533995.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值