Search code examples
javaconcurrencysynchronizationcyclicbarrier

Accessing output from barrier action in CyclicBarrier


I was practicing this question from oracle blog about happens before, i have a question in how to obtain/access the output of a barrier action in CyclicBarrier.

The blog link

https://blogs.oracle.com/javamagazine/post/quiz-yourself-happens-before-thread-synchronization-in-java-with-cyclicbarrier

the code

 public class CBTest {

    private List<Integer> results = Collections.synchronizedList(new ArrayList<>());
    
    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) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }

    void doCalculation() {
        CyclicBarrier cb = new CyclicBarrier(2, () -> {
            var ans = results.stream().mapToInt(v -> v.intValue()).sum();
            System.out.println("ANS IS "+ans);
            });
        new Calculator(cb, 2).start();
        new Calculator(cb, 3).start();
    }


    public static void main(String[] args) {
        var test = new CBTest();
        test.doCalculation();
    }
  }

please let me know on how to obtain the value of the cyclic barrier action ans in the main method?


Solution

  • You can make doCalculation return result synchronously by using a additional CountDownLatch(CountDownLatch), in this case, your doCalculation method will be blocked until the calculation result is generated:

        CountDownLatch countDownLatch = new CountDownLatch(1);
    
        int doCalculation() throws InterruptedException {
            AtomicInteger result = new AtomicInteger();
            CyclicBarrier cb = new CyclicBarrier(2, () -> {
                result.set(results.stream().mapToInt(v -> v.intValue()).sum());
                // count down
                countDownLatch.countDown();
            });
            new Calculator(cb, 2).start();
            new Calculator(cb, 3).start();
            // block util it is countDown.
            countDownLatch.await();
            return result.get();
        }
    
        public static void main(String[] args) throws InterruptedException {
            var test = new CBTest();
            System.out.println("ANS IS " + test.doCalculation());
        }