Engineering Full Stack Apps with Java and JavaScript
A latch is a synchronizer that acts as a gate by delaying the progress of threads until it reaches a particular state. Once it reaches the terminal state, it cannot change state again and hence remains open forever.
A synchronizer object coordinates the control flow of threads based on its state. Examples are semaphores, barriers, and latches. Blocking queues can also act as synchronizers. You can also create your own synchronizers. Threads arriving at the synchronizer might be allowed to pass or forced to wait based on the state. They also provide methods to manipulate the state, and to wait for the synchronizer to enter the desired state.
CountDownLatch is a latch implementation that allows one or more threads to wait for a particular state. A counter is initialized to a positive number. The countDown method decrements the counter, and the await methods wait for the counter to reach zero or until the waiting thread is interrupted, or the wait times out.
Example: CountDownLatchExample.java
import java.util.concurrent.CountDownLatch;
public class CountDownLatchExample {
public void countdownlatchdemo(int threadCount) {
final CountDownLatch starter = new CountDownLatch(3);
for (int i = 0; i < threadCount; i++) {
new Thread() {
@Override
public void run() {
try {
starter.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread Running!!!");
}
}.start();
}
System.out.println("ALL THREADS WAITING!!!");
// Count down number of times CountDownLatch is initialized
starter.countDown();
starter.countDown();
starter.countDown();
}
public static void main(String[] args) {
CountDownLatchExample latch = new CountDownLatchExample();
latch.countdownlatchdemo(4);
}
}
Note:
1. An inner class cannot refer to non-final local variables from the parent thread. But an inner class can access any instance variables of the parent thread. If you need a thread which has access to parent thread class instance variables, one solution is to make it an inner thread class or an anonymous inner thread class.
2. Comment any one starter.countDown(); in the above code and see that threads will keep waiting as count is not zero.
3. Add more starter.countDown();. If you add more starter.countDown(); than required, nothing will happen.