It can be translated as countdown (CountDown) Latch. Needless to say, the latch means, as the name implies, to prevent progress. Here it means that the CountDownLatch.await() method will block the current thread before the countdown is 0.
CountDownLatch is a synchronous helper class that allows one or more threads to wait until a set of operations being performed in other threads.
CountDownLatch works similar to the Thread.join() method, and can be used for the collaboration between one group of threads and another group of threads. For example, the main thread needs a series of preparations before doing a job, and only if all these preparations are completed can the main thread continue its work. These preparations are independent of each other, so they can be executed concurrently to increase speed. In this scenario, CountDownLatch can be used to coordinate the scheduling between threads. In the era when threads were created directly (before Java 5.0), we can use Thread.join(). After JUC appears, because threads in the thread pool cannot be directly referenced, CountDownLatch must be used.
The CountDownLatch class is a synchronous counter. When constructing, the int parameter is passed. This parameter is the initial value of the counter. Every time the countDown() method is called, the counter is decremented by 1 and the counter is greater than 0, the await() method will block the program and continue execution. CountDownLatch can be regarded as a countdown latch, triggering a specific event when the count is reduced to 0. Using this feature, the main thread can wait for the end of the child thread. The following is an example of a simulated athlete competition.
A very typical application scenario of CountDownLatch is: there is a task that wants to be executed downward, but you must wait until other tasks are executed before you can continue to be executed downward. If our task that we want to continue to execute further calls the await() method of the CountDownLatch object, and the other tasks call the countDown() method on the same CountDownLatch object after executing their own tasks, the task that calls the await() method will keep blocking and waiting until the count value of the CountDownLatch object decreases to 0.
CountDownLatch function list
CountDownLatch(int count) Constructs a CountDownLatch initialized with a given count. // Make the current thread wait until the latch counts to zero, unless the thread is interrupted. void await()// Makes the current thread wait until the latch counts to zero, unless the thread is interrupted or the specified waiting time is exceeded. boolean await(long timeout, TimeUnit unit)// Decrement the count of the latch. If the count reaches zero, all waiting threads will be released. void countDown()// Returns the current count. long getCount()// Returns a string identifying this latch and its status. String toString()
CountDownLatch data structure
The UML class diagram of CountDownLatch is as follows:
CountDownLatch's data structure is simple, it is implemented through "shared locks". It contains sync objects, sync is the Sync type. Sync is an instance class, which inherits from AQS.
Example of CountDownLatch
The following is implemented through CountDownLatch: "main thread" waits for "5 child threads" to complete the "specified work (1000ms)" before continuing to run.
import java.util.concurrent.CountDownLatch;import java.util.concurrent.CyclicBarrier;public class CountDownLatchTest1 { private static int LATCH_SIZE = 5; private static CountDownLatch doneSignal; public static void main(String[] args) { try { doneSignal = new CountDownLatch(LATCH_SIZE); // Create 5 new tasks for(int i=0; i<LATCH_SIZE; i++) new InnerThread().start(); System.out.println("main await begin."); // "main thread" waits for the completion of 5 tasks in the thread pool to complete doneSignal.await(); System.out.println("main await finished."); } catch (InterruptedException e) { e.printStackTrace(); } } static class InnerThread extends Thread{ public void run() { try { Thread.sleep(1000); System.out.println(Thread.currentThread().getName() + " sleep 1000ms."); // Subtract the value of CountDownLatch by 1 doneSignal.countDown(); } catch (InterruptedException e) { e.printStackTrace(); } } }} Running results:
main await begin.Thread-0 sleep 1000ms.Thread-2 sleep 1000ms.Thread-1 sleep 1000ms.Thread-4 sleep 1000ms.Thread-3 sleep 1000ms.main await finished.
The result description: The main thread uses doneSignal.await() to wait for other threads to decrement doneSignal to 0. The other 5 InnerThread threads, each of them subtracts the value of doneSignal by 1 through doneSignal.countDown(); when doneSignal is 0, main will continue to execute after being awakened.
PS: Difference between CountDownLatch and CyclicBarrier:
(1) The function of CountDownLatch is to allow 1 or N threads to wait for other threads to complete execution; while CyclicBarrier allows N threads to wait for each other.
(2) The counter of CountDownLatch cannot be reset; the counter of CyclicBarrier can be used after reset, so it is called a looped barrier.