Technical Article => Programming => Java

CountDownLatch

CountDownLatch can be used in synchronizing behavior among threads, it makes one or more threads wait for some actions in other threads to be completed. It has a property count which defines how many countDown() need to be called before other threads which called await() to be waked up.

When a thread calls CountDownLatch.await(), the thread will be blocked until the value of count becomes 0. The initial value of count can be specified when creating the CountDownLatch instance. Every time when CountDownLatch.countDown() is called, the value of count will decrease by 1 until the value becomes 0. One thing to be noted is that the value of count cannot be reset. i.e, when count becomes 0, the CountDownLatch will not work anymore, the call to await() method will return immediately.

Normally, the use cases of CountDownLatch are:

When value of count is 1, it acts as a switch. All threads calling awiat() will wait until some other thread turns off the switch by calling countDown()

When value of count is n, one or more threads can wait for another n threads complete their operations or some thread executes n operations.

A typical example will be when one complete computation process consists of n operations, the main thread will call CountDownLatch.await() to wait for the sub tasks to be completed. Each sub task will do its job, the countDown() method will be called when each sub task completes. The main thread would resume its work when all sub tasks have been completed.

CountDownLatch has below major methods:

await() throws InterruptedException

When count is 0, this method will return immediately. Otherwise the method will block until count becomes 0 or the thread is interrupted

When count is 0, this method will return immediately. Otherwise the method will block until count becomes 0 or the thread is interrupted boolean await(long timeout, TimeUnit unit) throws InterruptedException

When count is 0, this method will return immediately. Otherwise the method will block until count becomes 0 or the thread is interrupted or the timeout reaches. When count becomes 0, it returns true, otherwise it returns false if timeout occurs and count is not 0.

When count is 0, this method will return immediately. Otherwise the method will block until count becomes 0 or the thread is interrupted or the timeout reaches. When count becomes 0, it returns true, otherwise it returns false if timeout occurs and count is not 0. countDown()

If count is 0, it will do nothing, otherwise, it will decrease count by 1.

If count is 0, it will do nothing, otherwise, it will decrease count by 1. long getCount()

Return current count value

CyclicBarrier

CyclicBarrier is also a synchronization mechanism for threads. It allows multiple threads to wait for each other until all threads reach some point. The Cyclic in its name means it can be reused.

One use case of CyclicBarrier is that if a door can be opened only with N keys at the same time, then people who holds a key of the door needs to synchronize with each other and come to the door from different places and open the door until every person reaches the door.

A code example of this is:

public class CyclicBarrierTest { public static void main(String[] args) { int num = 3; CyclicBarrier barrier = new CyclicBarrier(num); ExecutorService service = Executors.newFixedThreadPool(num); for(int i = 1; i <= num; ++i) { service.submit(new Worker(barrier, i*1000)); } System.out.println("Main thread executing..."); service.shutdown(); } static class Worker implements Runnable { CyclicBarrier barrier = null; int waitTime = 0; public Worker(CyclicBarrier barrier, int waitTime) { this.barrier = barrier; this.waitTime = waitTime; } public void run() { try { Thread.sleep(waitTime); } catch (InterruptedException ex) { System.out.println(ex.getMessage()); } System.out.println("Preparing task..."); try { barrier.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } System.out.println("Task is completed"); } } }

The message "Preparing task..." will be printed three times before any "Task is completed" is printed.

CyclicBarrier has below major methods:

await

Block the current thread until all participating threads call this method. It can be interrupted and it can also timeout if timeout value is passed.

Block the current thread until all participating threads call this method. It can be interrupted and it can also timeout if timeout value is passed. reset

Reset the CyclicBarrier instance so that it can be reused.

CountDownLatch vs CyclicBarrier