CyclicBarrier的使用和常见问题

1、什么是CyclicBarrier?

CyclicBarrier也叫同步屏障,在JDK1.5被引入,可以让一组线程达到一个屏障时被阻塞,直到最后一个线程达到屏障时,所以被阻塞的线程才能继续执行。
CyclicBarrier好比一扇门,默认情况下关闭状态,堵住了线程执行的道路,直到所有线程都就位,门才打开,让所有线程一起通过。(引于深入浅出java CyclicBarrier -- 战小狼,感觉这个比喻很好)

2、构造方法

默认构造函数 CyclicBarrier(int parties) parties阻塞线程数据
CyclicBarrier(int parties, Runnable barrierAction) parties 阻塞线程数据,barrierAction线程执行前先运行此runnable。

3、CyclicBarrier阻塞和运行示例

  如果线程数达不到5,会一直等待或者是超时中断(await(时间))

  以快递打包为例,5个货物为一箱,先将五个货物都拿到再进行打包,代码如下:

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

        /**
         * CyclicBarrier 有两个构造方法 parties 总计数,runnable是 现在执行前先执行的方法
         * CyclicBarrier barrier = new CyclicBarrier(5);
         */
        CyclicBarrier barrier = new CyclicBarrier(5, () -> {
            System.out.println("开始货物打包");
        });

        ExecutorService executorPool = Executors.newCachedThreadPool();

        /**
         * await提供了两个方法
         * 1、await()
         * 2、await(long timeout, TimeUnit unit) 超时写法,且需捕获异常 TimeOutException
         */
        for (int i = 0; i < 11; i++) {
            int num = i;
            Thread.sleep(1000);
            executorPool.execute(() -> {
                try {
                    System.out.println(num + "号货物,已准备好,等待打包");
                    //barrier2.await(2, TimeUnit.SECONDS);
                    barrier.await();
                    System.out.println(num + "号货物,打包完成");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            });
        }
        executorPool.shutdown();
    }

4、其他

   ①、isBroken()方法检测Barrier是否被破坏

   ②、await(long timeout, TimeUnit unit) 超时写法,且需捕获异常 TimeOutException

   ③、如果有线程已经处于等待状态,调用reset方法会导致已经在等待的线程出现BrokenBarrierException异常。并且由于出现了BrokenBarrierException,将会导致始终无法等待。

   ④、getNumberWaiting() 获取正在等待的线程数

5、CyclicBarrier的底层原理

CyclicBarrier类是concurrent并发包下的一工具类。
线程间同步阻塞是使用的是ReentrantLock,可重入锁
线程间通信使用的是Condition,Condition 将 Object 监视器方法(wait、notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用。


 

猜你喜欢

转载自blog.csdn.net/luoyeyeyu/article/details/86495208
今日推荐