You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在main方法中获取CyclicBarrier屏障动作的输出结果

实现方案

你需要同时解决两个核心问题:

  • 将屏障动作中计算的ans存储到可被main方法访问的共享位置
  • 保证main方法读取值时,屏障动作已经完成计算,符合Java的happens-before可见性规则

具体修改步骤

  1. 给CBTest类新增一个volatile修饰的成员变量,用于存储计算结果,保证多线程下的可见性
  2. 在屏障动作中把计算得到的ans赋值给这个成员变量
  3. 让main线程等待所有计算线程执行完成后,再读取这个成员变量的值

修改后完整代码

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CyclicBarrier;

public class CBTest {
    private List<Integer> results = Collections.synchronizedList(new ArrayList<>());
    // 新增volatile修饰的成员变量存储结果,保证可见性
    private volatile int sumResult;

    class Calculator extends Thread {
        CyclicBarrier cb;
        int param;

        public Calculator(CyclicBarrier cb, int param) {
            this.cb = cb;
            this.param = param;
        }

        public void run() {
            try {
                results.add(param);
                System.out.println("going to await");
                cb.await();
            } catch (InterruptedException | BrokenBarrierException e) {
                e.printStackTrace();
            }
        }
    }

    // 方法修改为返回两个计算线程的实例,供main调用join等待
    Calculator[] doCalculation() {
        CyclicBarrier cb = new CyclicBarrier(2, () -> {
            var ans = results.stream().mapToInt(v -> v.intValue()).sum();
            System.out.println("ANS IS " + ans);
            // 把计算结果赋值给成员变量
            sumResult = ans;
        });
        Calculator t1 = new Calculator(cb, 2);
        Calculator t2 = new Calculator(cb, 3);
        t1.start();
        t2.start();
        return new Calculator[]{t1, t2};
    }

    public static void main(String[] args) throws InterruptedException {
        var test = new CBTest();
        Calculator[] threads = test.doCalculation();
        // 等待两个计算线程全部执行完成,此时屏障动作已经执行完毕
        for (Calculator t : threads) {
            t.join();
        }
        // 直接读取结果即可
        int ansFromBarrier = test.sumResult;
        System.out.println("main方法拿到的结果:" + ansFromBarrier);
    }
}

原理说明

根据CyclicBarrier的happens-before规则:

  • 所有线程中await()调用之前的操作,都优先于屏障动作中的操作执行
  • 屏障动作中的所有操作,都优先于所有线程从await()返回之后的操作执行
    所以当main通过join等待两个计算线程全部执行完成后,读取到的sumResult一定是屏障动作计算完成后的正确值,不存在可见性问题。

内容的提问来源于stack exchange,提问作者Umar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 09:06:01