Java Concurrency of CountDownLatch (waiting for multiple concurrent events to complete) Introducing the CountDownLatch class Concrete examples of the CountDownLatch class CountDownLatch Summary
Java introduced the CountDownLatch class after JDK 1.5. This class is a synchronization helper class. Used for a thread to wait for multiple operations to complete before executing, i.e. this current thread will keep blocking until the multiple operations it is waiting for have completed. First the CountDownLatch class is initialized, setting the number of operations it needs to wait for to complete. Then whenever an operation is completed, the countDown method is called, which decrements the counter inside CountDownLatch by one. When reduced to 0, the CountDownLatch class wakes up all threads that have gone dormant by calling the await method.
Without further ado, let's look at one specific example to understand the use of the CountDownLatch class.
Let's take the most intuitive example, let's say we need to have a video conference, and this conference needs to wait for a certain number of people to arrive before the conference starts. This situation would be ideal for using the CountDownLatch class for synchronization, that is, waiting for multiple concurrent events to occur, since the arrival of each participant is concurrent.
First we implement the meeting class, which holds an object of the CountDownLatch class and defines an arrive method that will be called whenever a meeting person arrives, telling the meeting that it has arrived, and this method, which calls the CountDown method, will subtract the counter by one.
In the run method of the meeting class, before announcing the start of the meeting, the await method of the CountDownLatch class is called to sleep until countDown decreases to 0, that is, the counter decreases to 0, indicating that all people have arrived, before waking up the code that continues the thread and announcing the start of the meeting
package CountDown; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; public class VideoConference implements Runnable { private final CountDownLatch controller; public VideoConference(int number) { controller = new CountDownLatch(10); } public synchronized void arrive(String name) { System.out.println(name + " has arrived."); System.out.println("VideoConference : waiting for " + (controller.getCount() - 1) + " partivipants"); controller.countDown(); } @Override public void run() { System.out.println("VideoConference : Innitiaization : " + controller.getCount() + " participants"); try { controller.await(); System.out.println("All people has come"); System.out.println("Let's start..."); } catch (InterruptedException e) { e.printStackTrace(); } } }
Next we implement the participant's class, which also implements the runnable interface, and first it holds a meeting object in order to call the drive method on execution to tell the meeting that the participant has arrived.
package CountDown; import java.util.concurrent.TimeUnit; public class Participant implements Runnable { private VideoConference conference; private String name; public Participant(VideoConference conference, String name) { this.conference = conference; this.name = name; } @Override public void run() { long duration = (long)Math.random() * 10; try { TimeUnit.SECONDS.sleep(duration + 10); } catch (InterruptedException e) { e.printStackTrace(); } conference.arrive(name); } }
Finally we implement the test class
package CountDown; public class Main { public static void main(String[] args) { VideoConference conference = new VideoConference(10); new Thread(conference).start(); for(int i=0;i<10;i++) { Participant p = new Participant(conference, "Participant " + i); new Thread(p).start(); } } }
Results of the run.
image.png
The await method also allows you to specify the time of hibernation, when the hibernation time is up or the counter is reduced to 0, it will wake up all the threads that are hibernated by CountDownLatch, then we can use this hibernation time to set here, we will only wait for the middle of 10s, if in 10s, there are still people who haven't arrived, we don't care and start the session first.
Only a simple modification to the run method is required.
@Override public void run() { System.out.println("VideoConference : Innitiaization : " + controller.getCount() + " participants"); try { controller.await(10, TimeUnit.SECONDS); if(controller.getCount() == 0) { System.out.println("All people has come"); System.out.println("Let's start..."); } else { System.out.println(" No more waiting."); System.out.println("Let's start..."); } } catch (InterruptedException e) { e.printStackTrace(); } }
running result
image.png
CountDownLatch has three basic elements.