1. Overview
CountDownLatch is a synchronizer tool class, which is used to coordinate the synchronization between multiple threads. It can make a thread continue to execute after waiting for other threads to complete their work. It cannot be reset.
2. Realize
A counter is used for implementation. The initial value of the counter is the number of threads. When each thread completes its own task, the value of the counter will be reduced by one. When the value of the counter is 0, the thread waiting on CountDownLatch can resume executing the next task.
3. Shortcomings
CountDownLatch is one-time. The value of the calculator can only be initialized once in the construction method. After that, there is no mechanism to set the value again. When CountDownLatch is used, it cannot be used again.
4. Method description:
- public void countDown(): decrements the count of the latch. If the count reaches zero, all waiting threads will be released. If the current count is greater than zero, the count is reduced
- public viod await() /boolean await(long timeout,TimeUnit unit): causes the current thread to wait until the latch counts down to zero, unless the thread is interrupted or exceeds the specified wait time. If the current count is zero, this method immediately returns a value of true. When the thread calls this method of the CountDownLatch object, the current thread will be blocked and will not return until one of the following occurs:
- If the count reaches zero, the method returns a value of true.
- If the current thread, the interrupt state of the thread has been set when entering this method; Or it is interrupted while waiting, an InterruptedException is thrown, and the interrupted state of the current thread is cleared.
- If the specified waiting time is exceeded, the return value is false. If the time is less than or equal to zero, the method will not wait at all. Parameters: timeout - the longest time to wait, and the time unit of the unit timeout parameter
5. Usage
- A thread waits for n threads to finish executing before starting to run
- Maximum parallelism of multiple threads starting to execute tasks (multiple threads waiting for one thread to complete)
5.1 method I
Before a thread starts running, wait for n threads to finish executing. Set await() for a thread. When CountDownLatch is 0, execute the current thread.
public class Test { /** * Set the counter size to 5 */ private static CountDownLatch latch = new CountDownLatch(5); public static void loading(int num) { System.out.println("The number of counters is:" + num); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } latch.countDown(); } public static void main(String[] args) { new Thread(() -> { for (int i = 5; i >= 1; i--) { loading(i); } }, "t1").start(); // Wait for 5 t1 threads to complete execution try { latch.await(); System.out.println("Execute main thread"); } catch (InterruptedException e) { e.printStackTrace(); } } }
effect:
5.2 method II
Realize the maximum parallelism of multiple threads starting to execute tasks. For example, set the initialization value of CountDownLatch() to 1, and multiple threads perform countdownlatch at the same time Await(), when the counter value is 0, multiple threads run at the same time (multiple threads wait for other threads to execute after completion).
public class Test { /** * Set the counter size to 1 */ private static CountDownLatch latch = new CountDownLatch(1); public static void main(String[] args) { for (int i = 5; i >= 1; i--) { new Thread(() -> { try { System.out.println(Thread.currentThread().getName() + "-In preparation"); latch.await(); System.out.println(Thread.currentThread().getName() + "-Completed"); } catch (Exception e) { e.printStackTrace(); } }).start(); } // Wait a second for the other threads to be ready try { TimeUnit.SECONDS.sleep(1); System.out.println("Execute main thread"); latch.countDown(); } catch (Exception e) { e.printStackTrace(); } } }
effect: