Talk about the understanding of java thread (two) -------- keyword join

Well, in the previous article, we have a preliminary understanding of the creation and operation of threads, so let's talk about the keyword join

Partners who are a little familiar with java threads know that Synchronized can add locks to prevent multithreading from preempting resources, improve data security, and so on. Of course, when you mention Synchronized, you may also think of join, wait, notify, and so on.

Let's talk about join first, this word is familiar to everyone, which means to become a member of; join; join;.

Let's look at a program.

package com.example.thread;

public class MyThreadPool {

    public static void main(String[] args) throws Exception {

        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("线程一开始"+Thread.currentThread());
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("线程一结束"+Thread.currentThread());
            }
        });

        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("线程二开始"+Thread.currentThread());
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("线程二结束"+Thread.currentThread());
            }
        });
        System.out.println("main 方法开始。。。。"+Thread.currentThread());

        thread1.start();
        thread2.start();

//        thread1.join();
//        thread2.join();
        System.out.println("main 方法结束。。。。"+Thread.currentThread());
    }

}

Let's look at the results of the operation below:

main 方法开始。。。。Thread[main,5,main]
main 方法结束。。。。Thread[main,5,main]
线程一开始Thread[Thread-0,5,main]
线程二开始Thread[Thread-1,5,main]
线程一结束Thread[Thread-0,5,main]
线程二结束Thread[Thread-1,5,main]

Process finished with exit code 0

There is nothing wrong with this. The main thread is started by adding two threads, and then the multithreading runs without affecting each other. It takes time for thread one and thread two to start, so the main thread ends first. Then thread one and thread two are started, waiting for 5 seconds will obviously end.

What if join is added? Let's look at the results of the operation:

main 方法开始。。。。Thread[main,5,main]
线程二开始Thread[Thread-1,5,main]
线程一开始Thread[Thread-0,5,main]
线程二结束Thread[Thread-1,5,main]
线程一结束Thread[Thread-0,5,main]
main 方法结束。。。。Thread[main,5,main]

Let’s take a look, there is no problem with the main thread starting first, and then thread 1 and thread 2 are started. They are too short apart and do not affect each other. So at the beginning, it may not be the first to output, but it must be before the main method. It ends first. why? join! Because thread one and thread two call the join method!

Let's take a look at the operation of this program. First, the three threads are started without affecting each other (before the join method is called), and then both thread one and thread two call join. First, thread one calls join, and thread one is sandwiched. The main thread starts between the end, and then thread two calls join again, and also jumps to the middle, so the methods of thread two and thread one finish first.

Why then?

Let's take a look at the source code of join():

 public final synchronized void join(long millis)
    throws InterruptedException {
        long base = System.currentTimeMillis();
        long now = 0;

        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

        if (millis == 0) {
            while (isAlive()) {
                wait(0);
            }
        } else {
            while (isAlive()) {
                long delay = millis - now;
                if (delay <= 0) {
                    break;
                }
                wait(delay);
                now = System.currentTimeMillis() - base;
            }
        }
    }

From the code, we can find out. When millis==0, it will enter the while( isAlive()) loop; that is, as long as the child thread is alive, the main thread will keep waiting.

Therefore, thread one and thread two actually preempt the resources of the main method, and if they jump in the queue to the front, they will naturally finish running first.

Okay, let’s get here today and add Synchronize tomorrow [laughing and crying]

 

no sacrifice,no victory!!!

Guess you like

Origin blog.csdn.net/zsah2011/article/details/107922351