This is the 13th day of my participation in Gwen Challenge

1. CountDownLatch usage scenario

CountDownLatch is a multithreaded utility class where the main methods are await and Countdown

Usage scenario: There are five business threads

Service thread 1, service thread 2, service thread 3, and service thread 4 wait until one of the tasks in service thread 3 and service thread 4 is completed, and then service thread 1 and service thread 2 continue to execute the tasks

2. The principle of CountDownLatch

The principle of CountDownLatch is that there is an internal counter, such as business thread 1 and business thread 2 waiting for three tasks to complete. You can instantiate a CountDownLatch with an initial value of 3, and then business thread 1 and business thread 2, After each step, call the await method on CountDownLatch. Business thread 1 and business thread 2 enter the wait state. Business thread 3 executes the countdown method on CountDownLatch after task 1. The initial value of CountDownLatch will change from 3 to 2 and continue with task 2. Upon completion, the countdown method will continue. Then business thread four will complete task 3 and CountDownLatch will become 0, alerting business thread 1 and business thread 2 to continue with the remaining operations.

In the example above, it is possible that the business thread 4 will countdown first, but their count must be 3, and the initial value of CountDownLatch will still be 0

The initial value of CountDownLatch is actually thread-safe, and its internal implementation principle uses AQS, which we haven’t learned yet. AQS ensures the security of CountDownLatch’s Count, thus realizing the business scenario of title 1

CountDownLatch does not require a single thread to wait on it. Multiple threads can wait on CountDownLatch. The number of countdownlatches does not depend on the number of threads

3. Use CountDownLatch

public class UseCountDownLatch {
	
    static CountDownLatch latch = new CountDownLatch(6);

    /* Initialize thread */
    private static class InitThread implements Runnable{

        public void run(a) {
        	System.out.println("Thread_"+Thread.currentThread().getId()
        			+" ready init work......");
            latch.countDown();
            for(int i =0; i<2; i++) { System.out.println("Thread_"+Thread.currentThread().getId()
            			+"... continue do its work"); }}}/* The business thread waits for the latch counter to complete with 0 */
    private static class BusiThread implements Runnable{

        public void run(a) {
            try {
                latch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            for(int i =0; i<3; i++) { System.out.println("BusiThread_"+Thread.currentThread().getId()
            			+" do business-----"); }}}public static void main(String[] args) throws InterruptedException {
        new Thread(new Runnable() {
            public void run(a) {
            	SleepTools.ms(1);
                System.out.println("Thread_"+Thread.currentThread().getId()
            			+" ready init work step 1st......");
                latch.countDown();
                System.out.println("begin step 2nd.......");
                SleepTools.ms(1);
                System.out.println("Thread_"+Thread.currentThread().getId()
            			+" ready init work step 2nd......");
                latch.countDown();
            }
        }).start();
        new Thread(new BusiThread()).start();
        for(int i=0; i<=3; i++){ Thread thread =new Thread(new InitThread());
            thread.start();
        }

        latch.await();
        System.out.println("Main do ites work........"); }}Copy the code

The use of CountDownLatch is still very simple hahaha