This is the 24th day of my participation in the Gwen Challenge.More article challenges

Preface:

For multithreaded programming, a toolkit for java.util.concurrent has been developed since JDK 1.5, which provides a number of multithreaded utility classes that can be used in specific scenarios, including Semaphore, CountDownLatch, CyclicBarrier, sanozer and Phaser are commonly used multithreading tools. Today we mainly talk about the principle and application scenario of CountDownLatch.

CountDownLatch

Definition:

CountDownLatch is a synchronization utility class that is used to coordinate synchronization between multiple threads, or for communication between threads (rather than as a mutual exclusion). CountDownLatch’s main mechanism is to trigger an event when multiple threads (equal to the count value when CountDownLatch was initialized) have reached the expected state or completed the expected work. Other threads can wait for this event to trigger their own work. Threads that reach their expected state call CountDownLatch’s countDown method, while waiting threads call CountDownLatch’s await method. This is implemented using a counter. The initial value of the counter is the number of threads. As each thread completes its task, the counter is reduced by one. When the counter value is 0, all threads have completed some task, and the threads waiting on CountDownLatch can resume to perform the next task.

Usage Scenarios:

  1. A thread waits for n threads to complete before it starts running. Initialize CountDownLatch’s counter to new CountDownLatch(n). When a task thread completes, the counter is reduced by 1. Countdownlatch.countdown (). The thread awaiting () on CountDownLatch is awakened. A typical application scenario is that when starting a service, the main thread waits for multiple components to load before resuming execution.

Code examples:

/** * TODO ** @author taoze * @version 1.0 * @date 6/23/21 7:54pm */ public class CountdownLatchTest1 {public static void main(String[] args) { ExecutorService threadPool = Executors.newFixedThreadPool(3); final CountDownLatch latch = new CountDownLatch(3); for (int i = 0; i < 3; I++) {threadpool.execute (new Runnable() {@override public void run() {try {system.out.println (" child thread "+) Thread.currentthread ().getName() + "start executing "); Thread.sleep((long) (Math.random() * 1000)); System.out.println(" child Thread "+ thread.currentThread ().getName() +" done "); latch.countDown(); } catch (InterruptedException e) {e.printStackTrace(); }}}); } try {system.out.println (" main Thread "+ thread.currentThread ().getName()) +" wait for the child Thread to complete..." ); latch.await(); System.out.println(" main Thread "+ thread.currentThread ().getName() +" start executing...") ); } catch (InterruptedException e) { e.printStackTrace(); }}}Copy the code

Execution Result:

2. Achieve maximum parallelism when multiple threads start executing tasks. Note that parallelism, not concurrency, emphasizes that multiple threads start executing at the same time. Similar to a race, multiple threads are placed at the starting point, wait for the starting gun to go off, and then run at the same time. This is done by initializing a shared CountDownLatch(1) and initializing its calculator to 1. Multiple threads first countdownlatch.await() before starting the task. When the main thread calls countDown(), the counter becomes 0 and multiple threads are awakened at the same time.

Code examples:

/** * TODO ** @author taoze * @version 1.0 * @date 6/24/21 10:16am */ public class CountdownLatchTest2 {public static  void main(String[] args) { ExecutorService service = Executors.newCachedThreadPool(); final CountDownLatch cdOrder = new CountDownLatch(1); final CountDownLatch cdAnswer = new CountDownLatch(4); for (int i = 0; i < 4; I++) {Runnable Runnable = new Runnable() {@override public void run() {try {system.out.println (" runner "+) Thread.currentthread ().getName() + "waiting for judge to issue password "); cdOrder.await(); System.out.println(" contestant "+ thread.currentThread ().getName() +" accepted password "); Thread.sleep((long) (Math.random() * 10000)); System.out.println(" runner "+ thread.currentThread ().getName() +" destination "); cdAnswer.countDown(); } catch (InterruptedException e) { e.printStackTrace(); }}}; service.execute(runnable); } try { Thread.sleep((long) (Math.random() * 10000)); System.out.println(" judge "+ thread.currentThread ().getName()+" password to publish "); cdOrder.countDown(); System.out.println(" judge "+ thread.currentThread ().getName()+" password sent, waiting for all runners to finish "); cdAnswer.await(); System.out.println(" all runners have reached the end "); System.out.println(" ref "+ thread.currentThread ().getName()); } catch (InterruptedException e) { e.printStackTrace(); } service.shutdown(); }}Copy the code

Execution Result:

Ok! That’s all for today’s article. The above are the two ways of using CountDownLatch. I hope it will be helpful to you.

Neat makes for great code, and there’s only so much detail