Can someone help me to understand what Java CountDownLatch
is and when to use it?
I don't have a very clear idea of how this program works. As I understand all three threads start at once and each Thread will call CountDownLatch after 3000ms. So count down will decrement one by one. After latch becomes zero the program prints "Completed". Maybe the way I understood is incorrect.
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class Processor implements Runnable {
private CountDownLatch latch;
public Processor(CountDownLatch latch) {
this.latch = latch;
}
public void run() {
System.out.println("Started.");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
latch.countDown();
}
}
// -----------------------------------------------------
public class App {
public static void main(String[] args) {
CountDownLatch latch = new CountDownLatch(3); // coundown from 3 to 0
ExecutorService executor = Executors.newFixedThreadPool(3); // 3 Threads in pool
for(int i=0; i < 3; i++) {
executor.submit(new Processor(latch)); // ref to latch. each time call new Processes latch will count down by 1
}
try {
latch.await(); // wait until latch counted down to 0
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Completed.");
}
}
If you add some debug after your call to latch.countDown(), this may help you understand its behaviour better.
The output will show the Count being decremented. This 'count' is effectively the number of Runnable tasks (Processor objects) you've started against which countDown() has not been invoked and hence is blocked the main thread on its call to latch.await().
Best real time Example for countDownLatch explained in this link CountDownLatchExample
CountDownLatch
in Java is a type of synchronizer which allows oneThread
to wait for one or moreThread
s before it starts processing.CountDownLatch
works on latch principle, thread will wait until gate is open. One thread waits forn
number of threads specified while creatingCountDownLatch
.e.g.
final CountDownLatch latch = new CountDownLatch(3);
Here we set the counter to 3.
Any thread, usually main thread of application, which calls
CountDownLatch.await()
will wait until count reaches zero or it's interrupted by anotherThread
. All other threads are required to do count down by callingCountDownLatch.countDown()
once they are completed or ready to the job. as soon as count reaches zero, theThread
awaiting starts running.Here the count is get decremented by
CountDownLatch.countDown()
method.The
Thread
which calls theawait()
method will wait until the initial count reaches to zero.To make count zero other threads need to call the
countDown()
method. Once the count become zero the thread which invoked theawait()
method will resume (start its execution).The disadvantage of
CountDownLatch
is that it's not reusable: once the count become zero it is no longer usable.NikolaB explained it very well, However example would be helpful to understand, So here is one simple example...
As mentioned in JavaDoc (https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html), CountDownLatch is a synchronization aid, introduced in Java 5. Here the synchronization does not mean restricting access to a critical section. But rather sequencing actions of different threads. The type of synchronization achieved through CountDownLatch is similar to that of Join. Assume that there is a thread "M" which needs to wait for other worker threads "T1", "T2", "T3" to complete its tasks Prior to Java 1.5, the way this can be done is, M running the following code
The above code makes sure that thread M resumes its work after T1, T2, T3 completes its work. T1, T2, T3 can complete their work in any order. The same can be achieved through CountDownLatch, where T1,T2, T3 and thread M share same CountDownLatch object.
"M" requests :
countDownLatch.await();
where as "T1","T2","T3" does
countDownLatch.countdown();
One disadvantage with the join method is that M has to know about T1, T2, T3. If there is a new worker thread T4 added later, then M has to be aware of it too. This can be avoided with CountDownLatch. After implementation the sequence of action would be [T1,T2,T3](the order of T1,T2,T3 could be anyway) -> [M]
One good example of when to use something like this is with Java Simple Serial Connector, accessing serial ports. Typically you'll write something to the port, and asyncronously, on another thread, the device will respond on a SerialPortEventListener. Typically, you'll want to pause after writing to the port to wait for the response. Handling the thread locks for this scenario manually is extremely tricky, but using Countdownlatch is easy. Before you go thinking you can do it another way, be careful about race conditions you never thought of!!
Pseudocode: