Introduction to the usage of CyclicBarrier in Concurrent Programming Series

1. CyclicBarrier cycle barrier definition

Definition: cooperate with a specified number of threads to make these threads wait in front of the barrier until all threads reach the barrier, and then continue to execute together. After thread execution, this barrier can be used again, so it is called loop barrier.

2. Usage and principle of CyclicBarrier

  • Construction method, CyclicBarrier(int parties): parties specifies how many parts (threads) participate, which is called the number of participants.
  • Construction method, CyclicBarrier(int parties,Runnable barrierAction): barrierAction, a command that is executed once when all participants reach the barrier. After the last thread in a set of threads arrives (but before releasing all threads), the change command is executed in that thread, which is run only once at each barrier point. This barrier is useful if you want to update the shared state before proceeding with all threads.
    • int await() throws InterruptedException,BrowkenBarrierException: the thread execution process will call await() method to indicate that it has reached the barrier. The thread will block itself and wait for other threads to reach the barrier; When all threads reach the barrier, that is, the number of threads waiting is equal to the number of participants, all threads are released to continue execution. The return value int indicates the index number of the current thread. Note that the index number is reduced from parties-1 to 0. Broken barrierexception: the barrier is broken. When await is called or the barrier is broken during waiting, a broken barrierexception will be thrown.
    • Int await (long timeout, timeunit) throws interruptedexception, brokenbarrierexception, TimeoutException: wait for a specified length of time. If it cannot be released at the time, TimeoutException will be thrown
    • int getNumberWaiting(): gets the number of threads currently at the barrier
    • boolean isBroken(): judge whether the barrier is broken
    • void reset(): reset the barrier to the initialization state. If there are currently threads waiting, they will be released and a BrokenBarrierException will be thrown

3. Precautions for using CyclicBarrier

  • Be sure to have enough participant threads, otherwise they will always block at the barrier.
  • When using in the thread pool, pay attention to ensure that the number of threads in the thread pool is greater than or equal to the number of participants.

4. Applicable scenarios of CyclicBarrier

  • Threads waiting to execute together
  • Wait multiple times to execute together

5. Comparison between CountDownLatch and CyclicBarrier

  • CountDownLatch is that some threads wait for another thread to wake up
  • CyclicBarrier is a process in which participating threads wait for each other to arrive and execute together
  • CountDownLatch cannot be referenced circularly, and CyclicBarrier can be used circularly

6. CyclicBarrier example

  • Scenario: multi-stage waiting and starting together

Case: the company organizes weekend tourism activities. Everyone sets out from home to the company. After everyone arrives, they set out to the company to play, then gather at the gate of the park, and then eat in the restaurant. When everyone arrives, they begin to eat. Simulation scenarios are not programmed using.

The participants remained unchanged and waited for each other many times. The cyclic use feature of CyclicBarrier is just available

import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class CyclicBarrierExample {

    public static void main(String[] args) {
        int concurrency = 100;
        final CyclicBarrier cyclicBarrier = new CyclicBarrier(concurrency , ()->{
            System.out.println("*****************Ready to finish!************");
        });
        final Random random = new Random();
        for (int i = 0 ; i < concurrency; i++) {
            new Thread(() -> {
                try {
                    Thread.sleep(random.nextInt(10_000));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                System.out.println(Thread.currentThread().getName() + "Ready");
                try {
                    cyclicBarrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
                System.out.println(
                        Thread.currentThread().getName() + " start-up....");
            }).start();
        }
    }
}

Console printing:

... 
Thread-12 Ready
Thread-58 Ready
Thread-75 Ready
Thread-25 Ready
*****************Ready to finish!************
Thread-25 start-up....
Thread-89 start-up....
Thread-34 start-up....
...

Posted on Tue, 30 Nov 2021 07:31:45 -0500 by amargharat