Wednesday 19 June 2019

Java Concurrency : CyclicBarrier


Java Concurrency: CyclicBarrier

Let's learn about next topic: CyclicBarrier and we will see the difference between CountDownLatch and Cyclic Barrier.

The Cyclic Barrier gives a way to all the thread to wait for each other and reach a common point
to go ahead with further steps. It behaves the same as CountDownLatch but with only one
difference.
i.e.
CountDownLatch is used for one time only i.e. for ex starting an application we need to check
if the services is up then only start the program.
Once the count is Zero(0) program starts and there is the end of CountDownLatch.

But if there are some checkpoints in the application till where the threads can run parallel but
at that point threads have to wait for the other threads to get completed.
Once all the threads will reach that point then only execution proceeds.
This can be achieved by CyclicBarrier. Best thing with CyclicBarrier is we can reset it from time
to time unlike CountDownLatch.


Points to note:

Parties : threads which wait for each other to reach barrier,
Initialize the CyclicBarrier with the number of parties to wait
Parties will call await() method which is a blocking method as it will block every thread untill all
the thread reaches the barrier i.e. CyclicBarrier.await() .
Basically calling await() is shout out that Thread is waiting on the barrier.
await() is a blocking call but can be timed out or Interrupted by other thread.


Eg: CyclicBarrier with 3 thread. they will wait at barrier and then continue processing when all
thread reach the barrier

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.logging.Level;
import java.util.logging.Logger;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.logging.Level;
import java.util.logging.Logger;

public class CyclicBarrierExample {

private static class MyService implements Runnable {

private CyclicBarrier barrier;

public MyService(CyclicBarrier barrier) {
this.barrier = barrier;
}

@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + " waiting");
barrier.await();
System.out.println(Thread.currentThread().getName() + " crossed barrier");
} catch (InterruptedException ex) {
Logger.getLogger(CyclicBarrierExample.class.getName()).log(Level.SEVERE, null, ex);
} catch (BrokenBarrierException ex) {
Logger.getLogger(CyclicBarrierExample.class.getName()).log(Level.SEVERE, null, ex);
}
}
}

public static void main(String args[]) {

CyclicBarrier barrier = new CyclicBarrier(3, new Runnable() {
@Override
public void run() {
System.out.println("All the threads reached the barrier. ");
}
});

Thread t1 = new Thread(new MyService(barrier), "Execution of Thread 1");
Thread t2 = new Thread(new MyService(barrier), "Execution of Thread 2");
Thread t3 = new Thread(new MyService(barrier), "Execution of Thread 3");

t1.start();
t2.start();
t3.start();
}
}

Output:
Execution of Thread 3 waiting
Execution of Thread 2 waiting
Execution of Thread 1 waiting
All the threads reached the barrier.
Execution of Thread 1 crossed barrier
Execution of Thread 2 crossed barrier
Execution of Thread 3 crossed barrier

No comments:

Post a Comment