One example is given by one of our trainers when he was explaining difference between CountDownLatch and CyclicBarrier.
CountDownLatch: Suppose a stone can be lifted by
CountDownLatch: If we want all of our threads to do
something + countdown
so that other waiting (for count to reach zero) threads can proceed, we can use countdown latch. All prior threads who actually did the countdown can go on in this situation but there is no guarantee that line processed after latch.countdown() will be after waiting for other threads to reach at latch.countdown() but it has a guarantee that other waiting threads will only start further after latch.await() has reached zero.
CyclicBarrier: If we want all our thread to
do something + await at common point + do something
(each await call will decrease wait time for threads to carry on further)
CyclicBarrier functionality can be achieved by CountDownLatch only once by calling latch.countdown() followed by latch.await() by all the threads.
but again you cant reset/reuse the countdownlatch.
Best example where I used CyclicBarrier is to initialize multiple caches (warmed by multiple threads) and then starting further processing, and I wanted to reinitialize other caches again in Sync.