The principle Thread class join method

I. Introduction

join () is a method of the Thread class, according to the definition jdk document, the role of join () method is to wait for the end of the thread, that thread executing the current thread to wait another call join () method after the end of execution down. Thread execution is commonly used in the main the main thread, waiting for the other call join () method of the main end before proceeding with the main thread.

    /**
     * Waits for this thread to die.
     *
     */
    public final void join() throws InterruptedException
复制代码

II. Examples of Use

The following two examples, let's see what effect the use join () method is yes.

1. without using join () method

public class CreateThreadTest {
    public static void main(String[] args) {
        System.out.println("主线程执行开始");
        Thread threadA = new Thread(new RunnableTest(), "线程A");
        threadA.start();
        System.out.println("主线程执行结束");
    }
}

class RunnableTest implements Runnable{
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + "执行开始");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "执行结束");
    }
}
复制代码

Execution results are as follows:

主线程执行开始
线程A执行开始
主线程执行结束
线程A执行结束
复制代码

Because of these sub-thread execution time is relatively long, so after the end of the main thread to perform sub-thread execution until the end.

2. The use of the join () method

public class CreateThreadTest {
    public static void main(String[] args) {
        System.out.println("主线程执行开始");
        Thread threadA = new Thread(new RunnableTest(), "线程A");
        threadA.start();
        try {
            threadA.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("主线程执行结束");
    }
}

class RunnableTest implements Runnable{
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + "执行开始");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "执行结束");
    }
}
复制代码

Execution results are as follows:

主线程执行开始
线程A执行开始
线程A执行结束
主线程执行结束
复制代码

After the sub-thread threadA calls join () method, we found that the main thread will wait until after the child thread to continue down the end of the execution.

The principle method three .join ()

By following the Thread class source code (JDK1.8) to gain insight about the join () method:

    public final void join() throws InterruptedException {
        join(0);
    }

    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;
            }
        }
    }
复制代码

The code above, note the two codes, one of:

public final synchronized void join(long millis) throws InterruptedException {}
复制代码

Members of the synchronized method plus instructions are synchronized (this), who this is? this is threadA child thread object itself. In other words, the main thread holds the lock threadA this sub-thread object.

Second:

while (isAlive()) {
    wait(0); 
}
复制代码

Note that this wait () method is a method of the Object class, that is the main thread after executing wait () method will release the lock threadA object enters the waiting state until they were awakened again. As we all know, with the wait (), there must notify (), notify when will it? In jvm source in:

//一个c++函数:
void JavaThread::exit(bool destroy_vm, ExitType exit_type) ;
//里面有一个贼不起眼的一行代码
ensure_join(this);

static void ensure_join(JavaThread* thread) {
  Handle threadObj(thread, thread->threadObj());

  ObjectLocker lock(threadObj, thread);

  thread->clear_pending_exception();

  java_lang_Thread::set_thread_status(threadObj(), java_lang_Thread::TERMINATED);

  java_lang_Thread::set_thread(threadObj(), NULL);

  //同志们看到了没,别的不用看,就看这一句
  //thread就是当前线程,是啥?就是刚才例子中说的threadA线程
  lock.notify_all(thread);

  thread->clear_pending_exception();
}
复制代码

When the child thread threadA the end of execution, jvm will automatically wake up blocks on threadA thread object, in our case that is the main thread. So far, threadA thread object is notifyall, then the main thread also will be able to continue to run anymore.

IV. Summary

In the main the main thread calls threadA.join () method, because the join () method is a synchronized method, so the main thread will first hold a lock thread thread object . Next call join () method which wait () method, the main thread releases the lock thread thread object, into a wait state . Finally, threadA thread execution ends, JVM calls lock.notify_all (thread); wake threadA holds the object lock thread is the main thread, the main thread will continue down the implementation .


reference:

join () method principle [Java] Thread class

join method in Java Thread class in the end is how to achieve waiting for?

Guess you like

Origin juejin.im/post/5d7a52b2e51d4562092388f8