Join parsing of java concurrent

 When the main thread calls the join method of the sub-thread, the main thread enters wait and waits for the sub-thread to end or the waiting time is exceeded, and then the main thread and the sub-thread enter their respective preemption modes .

 

public class TestJoin implements Runnable {

    @Override
    public void run() {
        // synchronized (currentThread()) {
        for (int i = 1; i <= 5; i++) {
            try {
                sleep(1000);//Sleep for 5 seconds, the loop is for the convenience of outputting information
            } catch (InterruptedException e) {
                e.printStackTrace ();
            }
            System.out.println("睡眠" + i);
        }
        System.out.println("TestJoin finished");//t thread ends
    }
    //}

    public static void main(String[] sure) throws InterruptedException {
        Thread t = new Thread(new TestJoin());
        long start = System.currentTimeMillis();
        t.start();
        t.join(3000);//Wait for thread t 3000 milliseconds
        Long interval = System.currentTimeMillis()-start;
        System.out.println("Main finished after " + interval);//Print the end of the main thread
    }
}

 

It can be seen that if the main thread is t.join(3000); the first sub-thread will print out 3 sleeps, and then the main thread will continue to execute after 3000 seconds timeout.

If t.join() is called and no timeout is given, the main thread will wait for the child thread to end before continuing to execute.

 

The following is the source code of join, you can see that it is very clear "A timeout of {@code 0} means to wait forever ." 

    /**
     * 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;
            }
        }
    }

 

Also look at how wait(0); is handled:

public final native void wait(long timeout) throws InterruptedException;

 

There is such a sentence in the annotation of the method wait to explain that if wait(0), it will always wait to be notified and will not time out.

If
* {@code timeout} is zero, however, then real time is not taken into
* consideration and the thread simply waits until notified.
* </ul>

 

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326526803&siteId=291194637