关于Java CyclicBarrier reset的理解

1、在做leetcode中H2O 生成题目时用到了CyclicBarrier,于是尝试写了以下代码:

java 复制代码
package utils;

import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

public class H2O {
    private CyclicBarrier cb = new CyclicBarrier(3, new Runnable() {
        @Override public void run() {
            System.out.println("|");
            cb.reset();
        }
    });

    private int count = 5;

    public void pintH2O(){
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        executorService.execute(new Runnable() {
            @Override public void run() {
                for(int i = 0; i < count; i++){
                    System.out.print('H');
                    try{
                        cb.await();
                    } catch (Exception e){
                        System.out.print(" 1error " + e.toString());
                    }
                }
            }
        });

        executorService.execute(new Runnable() {
            @Override public void run() {
                for(int i = 0; i < count; i++){
                    System.out.print('H');
                    try{
                        cb.await();
                    } catch (Exception e){
                        System.out.print(" 2error " + e.toString());
                    }
                }
            }
        });

        executorService.execute(new Runnable() {
            @Override public void run() {
                for(int i = 0; i < count; i++){
                    System.out.print('O');
                    try{
                        cb.await();
                    } catch (Exception e){
                        System.out.print(" 3error " + e.toString());
                    }
                }
            }
        });

        executorService.shutdown();

    }
}

2、执行后产生了如下结果

java 复制代码
HHO|
O 1error java.util.concurrent.BrokenBarrierExceptionH 2error java.util.concurrent.BrokenBarrierExceptionH|
H 3error java.util.concurrent.BrokenBarrierExceptionO 1error java.util.concurrent.BrokenBarrierExceptionH|
H 3error java.util.concurrent.BrokenBarrierExceptionO 1error java.util.concurrent.BrokenBarrierExceptionH|
H 2error java.util.concurrent.BrokenBarrierExceptionH 3error java.util.concurrent.BrokenBarrierExceptionO|
 1error java.util.concurrent.BrokenBarrierException 2error java.util.concurrent.BrokenBarrierException
Process finished with exit code 0

3、在stackoverflow中发现了相同的问题Why CyclicBarrier reset() method is throwing BrokenBarrierException

原因如下:

(1)执行reset时,如果有线程正在等待屏障,则此线程会抛出BrokenBarrierException

(2)CyclicBarrier初始化时配置的Runnable(barrierAction),会在所有线程突破屏障后,由最后一个到达的线程去执行,这就解释了为什么第一次没有线程抛BrokenBarrierException,而后每次都另外2个线程抛出异常

(3)直观看来,reset做了2件事情:1、突破当前屏障;2、生成一个新屏障

(4)在查看以下源码后发现:无论是reset还是屏障被突破,都会生成一个新的generation instance,所以在循环中时不必调用reset,一般情况下也用不到此方法,上述代码把reset去掉即可正常执行

java 复制代码
public class CyclicBarrier {
    /**
     * Each use of the barrier is represented as a generation instance.
     * The generation changes whenever the barrier is tripped, or
     * is reset. There can be many generations associated with threads
     * using the barrier - due to the non-deterministic way the lock
     * may be allocated to waiting threads - but only one of these
     * can be active at a time (the one to which {@code count} applies)
     * and all the rest are either broken or tripped.
     * There need not be an active generation if there has been a break
     * but no subsequent reset.
     */
    private static class Generation {
        boolean broken = false;
    }
....

参考:

CyclicBarrier的克星---BrokenBarrierException

相关推荐
丶小鱼丶3 分钟前
并发编程之【优雅地结束线程的执行】
java
市场部需要一个软件开发岗位8 分钟前
JAVA开发常见安全问题:Cookie 中明文存储用户名、密码
android·java·安全
忆~遂愿12 分钟前
GE 引擎进阶:依赖图的原子性管理与异构算子协作调度
java·开发语言·人工智能
MZ_ZXD00116 分钟前
springboot旅游信息管理系统-计算机毕业设计源码21675
java·c++·vue.js·spring boot·python·django·php
PP东19 分钟前
Flowable学习(二)——Flowable概念学习
java·后端·学习·flowable
ManThink Technology24 分钟前
如何使用EBHelper 简化EdgeBus的代码编写?
java·前端·网络
invicinble28 分钟前
springboot的核心实现机制原理
java·spring boot·后端
人道领域36 分钟前
SSM框架从入门到入土(AOP面向切面编程)
java·开发语言
大模型玩家七七1 小时前
梯度累积真的省显存吗?它换走的是什么成本
java·javascript·数据库·人工智能·深度学习
CodeToGym1 小时前
【Java 办公自动化】Apache POI 入门:手把手教你实现 Excel 导入与导出
java·apache·excel