This is the 11th day of my participation in the August More Text Challenge. For details, see:August is more challenging

WangScaler: an author who works with his heart.

Statement: talent and learning shallow, if there is a mistake, kindly correct.

Multi-threading, distributed, high concurrency are common interview questions, so we must master the knowledge and key points. The beginning of mastery is learning, knowledge is such a little bit of accumulation, so today we will learn to learn the knowledge related to multi-program, how to judge the end of the thread.

The sample

The main function starts six new threads. The main thread waits for the six threads to finish before executing. Or does the main thread start all 6 threads and then go straight down? The following is an example:

package com.wangscaler.lock;
​
/ * * *@author WangScaler
 * @date2021/8/9 15:47 * /public class ThreadEnd {
    public static void main(String[] args) {
        int num = 6;
        for (int i = 0; i < num; i++) {
            new Thread(() -> {
                String name = "Thread" + Thread.currentThread().getName();
                System.out.println(name + "In progress.");
            }, String.valueOf(i)).start();
        }
        System.out.println("All threads have executed."); }}Copy the code

In a single thread, the program executes from top to bottom, so you might expect to print out all threads until all six threads have executed. However, this is not the case. In this case, the six threads are not directly related to the main thread, so the result is as follows:

Thread 0 is executing thread 2 is executing thread 1 is executing thread 3 is executing all threads are finished thread 4 is executing thread 5Copy the code

Multiple threads are executed simultaneously. After the mian thread starts the new thread, the mian thread will continue to execute downward, while the execution process of the new 6 threads is not associated with the main thread. So how can we ensure that all 6 threads are executed? Let’s look at some of the solutions below.

1, CountDownLatch

As the name suggests, countDown() is a decrement counter. Every time countDown() is called, the counter subtracted by one. Initially when we generated the CountDownLatch object, we specified that the number of CountDownLatch was the same as the number of threads. Every time thread execution ends, countDown() is called to subtract one.

The following is an example:

package com.wangscaler.lock;
​
import java.util.concurrent.CountDownLatch;
​
/ * * *@author WangScaler
 * @date2021/8/9 15:47 * /public class ThreadEnd {
    public static void main(String[] args) throws InterruptedException {
        int num = 6;
        CountDownLatch countDownLatch = new CountDownLatch(num);
        for (int i = 0; i < num; i++) {
            new Thread(() -> {
                String name = "Thread" + Thread.currentThread().getName();
                System.out.println(name + "In progress.");
                countDownLatch.countDown();
            }, String.valueOf(i)).start();
        }
        countDownLatch.await();
        System.out.println("Six threads are finished."); }}Copy the code

Using countDownLatch. Await (); The thread blocks until the number of threads is reduced to zero. So the main thread is blocked while the above six threads are not finished, only if countdownlatch.await (); When released, it proves that the above six threads have finished executing, reducing the total number of CountdownLatches to zero.

2, CyclicBarrier

In contrast to CountDownLatch, it allows a set of threads to wait (that is, enter wait after each thread completes) until a common barrier point is reached (all threads are waiting to complete) before they can start. For example, when we go to dinner with our friends, there is such a etiquette that we all sit and wait until everyone is complete. Only when everyone is complete can we use chopsticks. The number of people is like a barrier, preventing us from eating. So the above example can be done as well.

package com.wangscaler.lock;
​
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
​
/ * * *@author WangScaler
 * @date2021/8/9 15:47 * /public class ThreadEnd {
    public static void main(String[] args) {
        int num = 6;
        CyclicBarrier cyclicBarrier = new CyclicBarrier(num,()->{
            System.out.println("Six threads are finished.");
        });
        for (int i = 0; i < num; i++) {
            new Thread(() -> {
                String name = "Thread" + Thread.currentThread().getName();
                System.out.println(name + "In progress.");
                try {
                    cyclicBarrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch(BrokenBarrierException e) { e.printStackTrace(); } }, String.valueOf(i)).start(); }}}Copy the code

Runnable is executed only after all six threads have entered the wait, so we can tell if the thread is finished at Runnable. When all six threads are finished, call Runnable to print all six threads are finished.

3, activeCount

This parameter, I wrote in the previous article. Is the number of active threads in the thread used to return the current thread.

package com.wangscaler.lock;
​
​
/ * * *@author WangScaler
 * @date2021/8/9 15:47 * /public class ThreadEnd {
    public static void main(String[] args) {
        int num = 6;
        for (int i = 0; i < num; i++) {
            new Thread(() -> {
                String name = "Thread" + Thread.currentThread().getName();
                System.out.println(name + "In progress.");
            }, String.valueOf(i)).start();
        }
        while (Thread.activeCount()>2) {
            Thread.yield();
        }
        System.out.println("Six threads are finished."); }}Copy the code

When the number of active threads is greater than 2, the loop is detected, and when the number of threads is less than or equal to 2, the loop is terminated and the execution continues.

Why is the activeCount value greater than 2? Since the idea launch starts a Monitor Ctrl-break thread by default, the other thread is the thread that executes our main function. So when there are less than two threads, the other six threads must have finished.

4, exe. IsTerminated ()

package com.wangscaler.lock;
​
​
import java.util.concurrent.*;
​
/ * * *@author WangScaler
 * @date2021/8/9 15:47 * /public class ThreadEnd {
    public static void main(String[] args) throws InterruptedException {
        int num = 6;
        ExecutorService exe = Executors.newFixedThreadPool(num);
        for (int i = 0; i < num; i++) {
           exe.execute(() -> {
               String name = "Thread" + Thread.currentThread().getName();
               System.out.println(name + "In progress.");
           });
        }
        exe.shutdown();
        while (true) {
            if (exe.isTerminated()) {
                System.out.println("Six threads are finished.");
                break;
            }
            Thread.sleep(200); }}}Copy the code

6 threads are started in the thread pool. When the thread is finished, run the exe.shutdown() command. If the thread pool is closed, you can determine whether the thread has finished executing.

What else do you know about the end of a thread? Share out, learn together, progress together.

Here we are. Give us a thumbs-up before we go!

Pay attention to WangScaler, wish you promotion, pay rise, no bucket!