CyclicBarrier and Count DownLatch in Java
CyclicBarrier and CountDownLatch are both synchronization aids in Java’s java.util.concurrent package, but they serve different purposes and have distinct functionalities.
Table of Contents
CountDownLatch
- Purpose: CountDownLatch is used to make one or more threads wait until a set of operations being performed in other threads completes.
- Functionality: It has a counter that is decremented by calling the countDown() method. When the counter reaches zero, the threads waiting on the latch are released.
- Reusability: It is a one-time use synchronization aid. Once the count reaches zero, it cannot be reset or reused CyclicBarrier and Count DownLatch.
- Usage: Suitable for situations where you want to wait for a set of operations to complete (e.g., waiting for all services to start before starting the main application).
CyclicBarrier
- Purpose: CyclicBarrier is used to make a group of threads wait for each other to reach a common barrier point.
- Functionality: It allows a set of threads to wait for each other to reach a common barrier point before proceeding. The barrier is called cyclic because it can be reused after the waiting threads are released.
- Reusability: It can be reused after the waiting threads are released, hence suitable for cyclic barriers.
- Usage: Suitable for scenarios where threads need to wait for each other to reach a certain point before proceeding (e.g., multi-phase computations where threads must synchronize at the end of each phase).
Example
Example
Using CountDownLatch
java
import java.util.concurrent.CountDownLatch;
class Worker extends Thread {
private final CountDownLatch latch;
public Worker(CountDownLatch latch) {
this.latch = latch;
}
public void run() {
try {
System.out.println(Thread.currentThread().getName() + " is working.");
Thread.sleep(1000); // Simulate work
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
latch.countDown();
System.out.println(Thread.currentThread().getName() + " has finished.");
}
}
}
public class CountDownLatchExample {
public static void main(String[] args) {
final int threadCount = 3;
CountDownLatch latch = new CountDownLatch(threadCount);
for (int i = 0; i < threadCount; i++) {
new Worker(latch).start();
}
try {
latch.await(); // Wait for all workers to finish
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("All workers have finished. Proceeding with main thread.");
}
}
CyclicBarrier
java
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
class Task extends Thread {
private final CyclicBarrier barrier;
public Task(CyclicBarrier barrier) {
this.barrier = barrier;
}
public void run() {
try {
System.out.println(Thread.currentThread().getName() + " is waiting at the barrier.");
barrier.await(); // Wait at the barrier
System.out.println(Thread.currentThread().getName() + " has crossed the barrier.");
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
}
}
public class CyclicBarrierExample {
public static void main(String[] args) {
final int threadCount = 3;
CyclicBarrier barrier = new CyclicBarrier(threadCount, new Runnable() {
@Override
public void run() {
System.out.println("All parties have arrived at the barrier. Let's proceed.");
}
});
for (int i = 0; i < threadCount; i++) {
new Task(barrier).start();
}
}
}
Explanation CyclicBarrier and Count DownLatch
1. Using CountDownLatch:
- Three Worker threads are created and started.
- Each Worker thread performs some work (simulated by Thread.sleep(1000)) and then calls countDown() to decrement the latch count.
- The main thread calls await() on the latch and waits until all Worker threads have finished.
- Once the count reaches zero, the main thread proceeds CyclicBarrier and Count DownLatch.
2. Using CyclicBarrier:
- Three Task threads are created and started.
- Each Task thread waits at the barrier by calling await().
- When all threads reach the barrier, the barrier action (a Runnable that prints a message) is executed.
- After the barrier action, all threads proceed with their execution.