The lock is equivalent to a door. Before the lock reaches the end state, the door is always closed and no thread can pass. When the end state is reached, the door will open and allow all threads to pass. It can make one or more threads wait for a set of events to occur. The latching state consists of a counter, initialized to a formal, positive number indicating the number of events to wait for. The countDown method decrements the counter, indicating that an event has occurred, while the await method waits for the counter to reach 0, indicating that the awaited event has occurred. CountDownLatch emphasizes that one thread (or multiple threads) needs to wait for other n threads to complete something before continuing to execute.
Scenario application:
10 athletes prepare to run. They wait for the referee's order and start running at the same time. When the last person passes the finish line, the game ends. 10 movements are equivalent to 10 threads. The key here is to control 10 threads to run at the same time, and how to determine when the last thread has reached the end point. Two locks can be used. The first lock is used to control 10 threads waiting for the referee's order, and the second lock controls the end of the game.
import java.util.concurrent.CountDownLatch; class Aworker implements Runnable { private int num; private CountDownLatch begin; private CountDownLatch end; public Aworker(int num, final CountDownLatch begin, final CountDownLatch end) { this.num = num; this.begin = begin; this.end = end; } @Override public void run() { // TODO Auto-generated method stub try { System.out.println(num + "th people is ready"); begin.await(); //Ready} catch (InterruptedException e) { e.printStackTrace(); } finally { end.countDown(); // The counter decreases by one and reaches the end point System.out.println(num + "th people arrive"); } }} public class Race { public static void main(String[] args) { int num = 10; CountDownLatch begin = new CountDownLatch(1); CountDownLatch end = new CountDownLatch(num); for (int i = 1; i <= num; i++) { new Thread(new Aworker(i, begin, end)).start() ; } try { Thread.sleep((long) (Math.random() * 5000)); } catch (InterruptedException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } System.out.println("judge say: run!"); begin.countDown(); //Start running after the referee gives the order long startTime = System.nanoTime(); try { end.await(); //Wait for end} catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { long endTime = System.nanoTime(); System.out.println("judge say : all arrived !"); System.out.println("spend time: " + (endTime - startTime)); } }}
output
1th people is ready2th people is ready4th people is ready6th people is ready3th people is ready10th people is ready8th people is ready5th people is ready7th people is ready9th people is readyjudge say : run !1th people arrive4th people arrive10th people arrive5th people arrive2th people arrivejudge say : all arrived !9th people arrive7th people arrive8th people arrive3th people arrive6th people arrivepend time: 970933