This is the 18th day of my participation in the August Genwen Challenge.More challenges in August

scenario

There are 6 students and 1 student on duty in the classroom. The student on duty needs to finish the task of closing the door after all the other students have left the classroom. Then simulate the following code based on your requirements

public class CountDownLatchDemo {
    public static void main(String[] args) {
        for (int i = 1; i <= 6; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + "Leave the classroom ~~~");
            }, String.valueOf(i)).start();
        }
        System.out.println("The student on duty has closed the door and gone."); }}Copy the code

Running results:

No. 1 leaves the classroom ~~~ the student on duty closes the door and goes ~~ no. 2 leaves the classroom ~~ no. 3 leaves the classroom ~~ no. 6 leaves the classroom ~~ no. 5 leaves the classroom ~~ no. 4 leaves the classroom ~~~Copy the code

It can be seen that in the multi-threaded environment, the main thread performs the operation of closing the door of the student on duty before the other threads have finished executing (the other students have not left the classroom). Therefore, we introduce CountDownLatch under the java.util.Concurrent package to solve this problem

  • CountDownLatch has a positive counter, the countDown() method decrement the counter, and the await() method waits for the counter to reach zero. All await threads block until the counter reaches zero or wait for the thread to interrupt or time out.

The effect of locking (countdown lock)

  • Coordinate threads so that a thread waits until the countdown ends before starting execution
  • Can be applied to control the order in which threads are executed

Source code analysis

public CountDownLatch(int count) {
    if (count < 0) throw new IllegalArgumentException("count < 0");
    this.sync = new Sync(count);
}
Copy the code

Can see CountDownLatch maintains a inner class in Sync, and Sync inherited from AbstractQueuedSynchronizer, And there are a variable in AbstractQueuedSynchronizer private volatile int state; The visibility of the state variable is guaranteed

import java.util.concurrent.CountDownLatch;

public class CountDownLatchDemo {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(6);
        for (int i = 1; i <= 6; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + "Leave the classroom ~~~");
                countDownLatch.countDown();
            }, String.valueOf(i)).start();
        }
        countDownLatch.await();
        System.out.println("The student on duty has closed the door and gone."); }}Copy the code

Running results:

No. 1 student leaves the classroom ~~ no. 4 student leaves the classroom ~~ no. 6 student leaves the classroom ~~ no. 3 student leaves the classroom ~~ no. 2 student leaves the classroom ~~ no. 5 student on duty closes the door and leavesCopy the code