join method of Thread source code analysis

join method example 1

Source code

import java.util.concurrent.TimeUnit;


public class JoinWaitTest {

    private static int a = 0;
    private static int b = 100;

    public static void main(String... args) throws InterruptedException{
        Thread t = new Thread(new WaitThread());

        t.start();
        t.join();

        System.out.println("I'm waiting for WaitThread end.");
        System.out.println("The result is " + (a + b));
    }

    static class WaitThread implements Runnable {
        @Override
        public void run() {
            try {
                for (int i = 1; i < 6; i++) {
                    TimeUnit.SECONDS.sleep(1);
                    a++;
                    System.out.println(i);
                }
            } catch (InterruptedException e) {

            }
        }
    }
}

results of enforcement

1

2

3

4

5

I'm waiting for WaitThread end.

The result is 105

Scene description

In many cases, the main thread generates and starts the sub thread. If there are a lot of time-consuming operations in the sub thread, the main thread usually ends before the sub thread. However, if the main thread processes other transactions, it needs to use the processing results of the sub thread, that is, the main thread needs to wait for the execution of the sub thread before ending. At this time, it needs to use join() Method.

This example is just an example, which demonstrates the above process.

join method example 2

Source code

import java.util.concurrent.TimeUnit;


public class JoinTest {

    public static void main(String... args) throws InterruptedException {
        Thread jt = new Thread(new JoinThread());
        Thread tt = new Thread(new TimingThread());

        tt.start();
        tt.join();
        jt.start();

    }

    static class JoinThread implements Runnable {
        @Override
        public void run() {
            System.out.println("I have waited for too long.");
        }
    }

    static class TimingThread implements Runnable {
        @Override
        public void run() {
            for (int i = 0; i < 6; i++) {
                try {
                    TimeUnit.SECONDS.sleep(1);
                    System.out.println("Sleep end!");
                } catch (InterruptedException e) {

                }
            }
        }
    }
}

results of enforcement

Sleep end!

Sleep end!

Sleep end!

Sleep end!

Sleep end!

Sleep end!

I have waited for too long.

Scene description

It is the same as source code example 1, except that jt thread has to wait for tt thread to finish.

Source code analysis of join method

jdk source code

/**

     * Waits at most {@code millis} milliseconds for this thread to

     * die. A timeout of {@code 0} means to wait forever.

     *

     * <p> This implementation uses a loop of {@code this.wait} calls

     * conditioned on {@code this.isAlive}. As a thread terminates the

     * {@code this.notifyAll} method is invoked. It is recommended that

     * applications not use {@code wait}, {@code notify}, or

     * {@code notifyAll} on {@code Thread} instances.

     *

     * @param  millis

     *         the time to wait in milliseconds

     *

     * @throws  IllegalArgumentException

     *          if the value of {@code millis} is negative

     *

     * @throws  InterruptedException

     *          if any thread has interrupted the current thread. The

     *          <i>interrupted status</i> of the current thread is

     *          cleared when this exception is thrown.

     */

    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;

            }

        }

}

join source code analysis without parameters 1 -- essentially calling the wait method

The join() method is essentially join(0), and the final execution code is as follows

In essence, calling code 1 is equivalent to calling code 2

Source code analysis of join with parameters

Core code

A change:

while (isAlive()) {

            if (millis <= now) {

                break;

            }

            wait(millis - now);

            now = System.currentTimeMillis() - base;

        }

analysis

base and now are both time. base is the time when the code is just executed, and now is the time when the code is executed. Judge whether the mills time has passed. When the time has passed, break will jump out of the code.

Keywords: Java JDK

Added by jotgabbi on Tue, 17 Dec 2019 19:25:02 +0200