package br.com.leonardoz.features.synchronizers; import java.util.Random; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.Executors; /** * Barriers are used for blocking a group of threads until they come together at * a single point in order to proceed. Basically, convergence of threads. * * Accepts a runnable in it's constructor to be called when the threads reach the * barrier, but before its unblocked * * Most common implementation is cyclic barrier. * */ public class UsingBarriers { public static void main(String[] args) { Runnable barrierAction = () -> System.out.println("Well done, guys!"); var executor = Executors.newCachedThreadPool(); var barrier = new CyclicBarrier(10, barrierAction); Runnable task = () -> { try { // simulating a task that can take at most 1sec to run System.out.println("Doing task for " + Thread.currentThread().getName()); Thread.sleep(new Random().nextInt(10) * 100); System.out.println("Done for " + Thread.currentThread().getName()); barrier.await(); } catch (InterruptedException | BrokenBarrierException e) { e.printStackTrace(); } }; for (int i = 0; i < 10; i++) { executor.execute(task); } executor.shutdown(); } }