This is the 19th day of my participation in the Genwen Challenge

Peaches and plumes do not speak, yet a path is formed beneath them

Origin of things

I learned the Go language some time ago and learned that the key word Go in Go can enable the coroutine Goroutine to realize concurrency and parallelism. There is a WaitGroup in the Sync package that does the asynchronous to synchronous function of waiting for the end of a group of threads. The parent coroutine calls the Add method to set the number of waiting coroutines. Each waiting coroutine calls the Done method when the task is finished. At the same time, the parent coroutine calls the Wait method and blocks until all threads end.

For example, in another article: Go Cache breakdown solution – SingleFlight source code interpretation, SingleFlight uses waitGroup to implement other coroutines that wait until the execution of the coroutine executing the database request is complete before retrieving data. R2:call.wg.wait() will wait for R1: call.done() to complete before executing the following code.

So what about asynchronous to synchronous in Java?

CountDownLatch

CountDownLatch is a class in the Java package java.util.Concurrent that allows one or more threads to wait for other threads to complete before executing, thus achieving the same effect as WaitGroup in Go.

Talk is Cheap, Show me the code!

code

The test code is as follows:

package multi.thread.xxxxx.com;

import java.util.concurrent.CountDownLatch;

public class CountDownLatchTest {

	public static void main(String[] args) {
		final CountDownLatch latch = new CountDownLatch(2);

        new Thread(){
            public void run(a) {
                try {
                    System.out.println(Child thread+Thread.currentThread().getName()+"In process");
                   Thread.sleep(3000);
                   System.out.println(Child thread+Thread.currentThread().getName()+"Executed");
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
                latch.countDown();
            };
        }.start();

        new Thread(){
            public void run(a) {
                try {
                    System.out.println(Child thread+Thread.currentThread().getName()+"In process");
                    Thread.sleep(3000);
                    System.out.println(Child thread+Thread.currentThread().getName()+"Executed");

               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
               latch.countDown();
            };
        }.start();

        try {
            System.out.println("Wait for 2 child threads to complete...");
           latch.await();
           System.out.println("2 child threads have completed execution");
           System.out.println("Continue executing the main thread");
       } catch(InterruptedException e) { e.printStackTrace(); }}}Copy the code

Execution Result:

Child Thread thread-0 is executing and waiting for two child threads to finish executing... Child Thread Thread-1 Executing child Thread Thread-0 executing complete Child Thread Thread-1 executing complete Two child threads executing the main ThreadCopy the code

Note that the child thread throws an exception stack that cannot be caught in the main try-catch thread. Therefore, the child thread notices the catch exception and ensures that the countDown method is executed, so that the main thread cannot execute to the await method until it times out.