CountDownLatch

0

CountDownLatch is a signalling mechanism that allows one or more threads to wait until a set of operations being performed in other threads completes.

A CountDownLatch is initialized with a given count (the number of operations after which the waiting threads will wake up).
The await method blocks until the count of operations reaches zero. As each thread complete its assigned task, it calls countDown() to decrement the count.

For example, below we create a CountDownLatch of count 2, we start two threads which call await on it. Next, we call countDown() couple of times. Finally, we wait till the two threads are done awaiting.

public void testCountDownLatch() {
        final CountDownLatch latch = new CountDownLatch(2);
        final boolean done[] = new boolean[2];
        Thread t1 = new Thread(new Runnable(){
            public void run() {
                try {
                    latch.await();
                    done[0] = true;
                } catch (InterruptedException e) {
                    fail(e.toString());
                }
            }
        });
        t1.start();
        Thread t2 = new Thread(new Runnable(){
            public void run() {
                try {
                    latch.await();
                    done[1] = true;
                } catch (InterruptedException e) {
                    fail(e.toString());
                }
            }
        });
        t2.start();
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            fail(e.toString());
        }
        latch.countDown();
        latch.countDown();
        try {
            t1.join();
        } catch (InterruptedException e) {
            fail(e.toString());
        }
        try {
            t2.join();
        } catch (InterruptedException e) {
            fail(e.toString());
        }
        assertTrue(done[0] && done[1]);
    }

Class Diagram

 

 

CountDownLatch internally depends on the AbstractQueuedSynchronizer . Both await and countDown() methods delegate the call to the abstract class.

Await

 

 

await() delegates the call to AbstractQueuedSynchronizer. CountDownLatch implements the tryAcquireShared() method. If the count is 0 (internal state), it considers the latch as already released else will queue up the thread and will block the thread.

In the below diagram, we create a CountDownLatch for count 2. Next, we create two threads that wait for the release of latch. Initially when a thread calls await, it simply waits in a queue as the count is still != 0

 

CountDownLatch

Release

 

CountDownLatch

 

countDown() delegates the call to AbstractQueuedSynchronizer. CountDownLatch implements the tryReleaseShared() method. If the count is already 0 (internal state), it simply returns else decrements the count. If after decrementing, the count becomes zero then it will signal for the release of all the waiting threads.

In the below diagram, we call countDown() couple of times to release the latch. Whenever we call countDown(), the count decrements. Once it becomes equals to 0, the latch gets released and unparks the successor thread which in turn propagates the release to all the waiting threads.

 

CountDownLatch

 

 

Share.

Leave A Reply