How to reuse CyclicBarrier in Java?

Alan 183 Published: 10/14/2024

How to reuse CyclicBarrier in Java?

I'll respond in English as per your request!

In Java, the CyclicBarrier class is used to coordinate a fixed number of threads until all of them have reached the barrier. Once all threads have crossed the barrier, they can continue executing.

To reuse a CyclicBarrier, you need to reset it after it has been broken. Here's an example:

import java.util.concurrent.CyclicBarrier;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

public class ReuseCyclicBarrier {

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

final int numThreads = 3; // number of threads

final CyclicBarrier barrier = new CyclicBarrier(numThreads);

ExecutorService executor = Executors.newFixedThreadPool(numThreads);

for (int i = 0; i < numThreads; i++) {

int threadNumber = i;

Thread workerThread = new MyWorkerThread(barrier, threadNumber);

executor.submit(workerThread);

}

}

static class MyWorkerThread implements Runnable {

private final CyclicBarrier barrier;

private final int threadNumber;

public MyWorkerThread(CyclicBarrier barrier, int threadNumber) {

this.barrier = barrier;

this.threadNumber = threadNumber;

}

@Override

public void run() {

try {

// Some work

for (int i = 0; i < 3; i++) {

System.out.println("Worker " + threadNumber + ": Working...");

Thread.sleep(100); // Simulate some work

}

barrier.await(); // Wait until all threads have reached the barrier

System.out.println("Worker " + threadNumber + ": Barrier broken!");

} catch (InterruptedException e) {

Thread.currentThread().interrupt();

}

try {

// Some more work after barrier is broken

for (int i = 0; i < 2; i++) {

System.out.println("Worker " + threadNumber + ": Continuing...");

Thread.sleep(100); // Simulate some more work

}

barrier.reset(); // Reset the barrier to reuse it again

} catch (BrokenBarrierException e) {

Thread.currentThread().interrupt();

}

}

}

}

In this example, three threads are created and executed concurrently. Each thread performs some work, then reaches a CyclicBarrier and waits until all threads have reached the barrier. After the barrier is broken, each thread continues with more work, resetting the barrier for reuse.

Note that you need to call reset() on the CyclicBarrier to reuse it after it has been broken.

Keep in mind that this example is simplified for illustration purposes. In real-world scenarios, you might want to add additional error handling and synchronization mechanisms to ensure correct behavior.

Java cyclicbarrier example

I'll provide an explanation of the CyclicBarrier concept and demonstrate it with a Java code example. This barrier is designed to allow multiple threads to wait until all threads have reached a certain point, like starting a shared operation.

Java Code Example:

Here's a basic demonstration of how CyclicBarrier works in Java:

import java.util.concurrent.BrokenBarrierException;

import java.util.concurrent.CyclicBarrier;

public class Main {

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

// Create the barrier with 3 parties (threads)

final int numParties = 3;

CyclicBarrier barrier = new CyclicBarrier(numParties);

for (int i = 0; i < numParties; i++) {

// Each thread waits until all threads have reached the barrier

Thread t = new Thread(() -> {

try {

System.out.println("Thread " + i + " waiting at barrier");

barrier.await();

System.out.println("Thread " + i + " has passed the barrier");

} catch (InterruptedException e) {

throw new RuntimeException(e);

} catch (BrokenBarrierException e) {

throw new RuntimeException(e);

}

});

t.start();

}

}

}

Explanation:

Let's break down how this code works:

We create a CyclicBarrier object, specifying the number of threads that will participate in the barrier (numParties). In our example, we have 3 threads. Each thread creates an instance and sets up its own execution. Within each thread, we: Print a message indicating the thread is waiting at the barrier. Call barrier.await(). This method will cause the current thread to block until all parties (threads) have reached the barrier. Once the threads are all synchronized, print another message to indicate they've passed the barrier.

How CyclicBarrier Works:

When a thread calls await() on the barrier, it becomes blocked and waits for all other participating threads to reach the same point (the barrier). As each thread reaches the barrier, it continues execution without waiting. Once the last thread has reached the barrier, they are all "synchronized" - they have all reached the starting line. The await() method can throw an exception if some threads do not reach the barrier, effectively breaking the cycle.

Advantages of CyclicBarrier:

Thread coordination: Allows multiple threads to wait until a specific point in their execution. Synchronization: Ensures all participating threads have reached a common starting point before proceeding with shared operations.

In summary, Java's CyclicBarrier is an excellent tool for coordinating the flow of your application by allowing multiple threads to synchronize at a specified point.