The art of Java Concurrent Programming - thread join()

Content Description: sort out the inter thread communication in the art of Java Concurrent Programming and analyze thread When using the join () use case, I don't understand why wait() uses which thread

1. thread.join() case

Case description:

① Use new Thread(new Runnable(previous), i) to create a thread named i

② Each thread holds a reference to the previous thread, which calls thread Join() method

public class Join {
    public static void main(String[] args) throws InterruptedException {
        Thread previous = Thread.currentThread();
        for(int i = 0; i < 10; i++){
            Thread thread = new Thread(new Domino(previous), String.valueOf(i));
            previous = thread;
        System.out.println(Thread.currentThread().getName() + " terminate.");
    static class Domino implements Runnable{
        private Thread thread;
        public Domino(Thread thread){
            this.thread = thread;

        public void run() {
            try {
            } catch (InterruptedException e) {

            System.out.println(Thread.currentThread().getName() + " terminate.");

Operation results:

main terminate.
0 terminate.
1 terminate.

Comment thread. In run() Run results after join():

1 terminate.
2 terminate.
0 terminate.
main terminate.

Multiple inputs are out of order, and the print command of the main thread is executed last

2. ? wait for this thread to die

Comments of join() method in Thread class: waits for this thread to die

Question: who is the subject of waits? Who is this?

// Waits for this thread to die.
public final void join() throws InterruptedException {

First analyze this:
In depth understanding of JVM pg 236: the instance method accesses the object to which the method belongs through "this"

Is this in the bytecode file a thread in the Domino class?

Getfield: access class fields and instance fields, that is, the getfield instruction is for class objects or instance objects

Thread is the instance field of the instance object. Since thread is an attribute in Domino, the thread here should be the instance object of Domino, that is, the anonymous object here

Thread thread = new Thread(new Domino(previous), String.valueOf(i));

Note: This discussed here is not this that calls the join() method, but only to illustrate the relationship between thread and target in thread = new Thread(Runnable target)

3. thread && target

Constructor in Thread class:

Thread()Assign a new Thread object
Thread(Runnable target)Assign a new Thread object
Thread(Runnable target, String name)Assign a new Thread object and name it

There are 8 construction methods in Thread class. Please check for details jdk1.8api

Note: if target = null, execute the run method of the thread; otherwise, execute the run method of target

public Thread(Runnable target, String name) {
    init(null, target, name, 0);

Since there is only run() method in the Runnable interface, use new thread (Runnable target) Start () actually uses the proxy mode, and the thread object starts the run method in the target

Summary: when i = 0 first layer loop is executed, three instance objects thread, previous, new Domino(...) are actually involved

4. thread.start() && synchronized

poll the start method, because you notice that the method is synchronized

public synchronized void start() {
    try {
        started = true;
    } finally {

When you see synchronized, you think that calling wait() will release the lock. Thread executes the synchronized method, which indicates that the lock is obtained by thread. However, since main is a static method and starts after the JVM is opened, the lock held should be a class object, and there seems to be no relationship = =!!!

What is the lock object here? I haven't figured it out yet

5. isAlive( ) && wait()

Back to thread Join(), this method calls join(0) again

When the input parameter millis = 0: wait indefinitely

public final synchronized void join(long millis)
    throws InterruptedException {
        if (millis == 0) {
        // isAlive() determines whether the thread is alive
            while (isAlive()) {
            // Causes the current thread to wait until another thread calls notify() or notifyAll()

Although the run method of the new Domain() object is executed, the thread thread is started. Therefore, the two threads involved are new thread thread thread and previous thread respectively

Question: who is isAlive() judging who isalive?

//Tests if this thread is alive. A thread is alive if it has been started and has not yet died.
public final native boolean isAlive();

Note that this is used in the comment part instead of current. Does that mean that the current thread is looping to determine whether it is alive or not?

Not sure, but the comment section of the join(0) method gives a description:

* <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. 

Both isAlive() and wait() are called by the current object this, that is, the previous thread. This will be called when the thread terminates Notifyall() wakes up the waiting thread

So which thread is wait ing?

//Causes the current thread to wait until either another thread invokes the {@link java.lang.Object#notify()} method...
public final native void wait(long timeout) throws InterruptedException;

Note: the comment section uses current thread instead of this thread

So which thread is current thread?

6. current thread && object

It has been analyzed above that the Thread executing the run method is the Thread thread

Thread thread = new Thread(new Domino(previous), String.valueOf(i));

The picture comes out like this: I feel there is something wrong and need to continue learning. Welcome to correct

That is, the current thread is the thread created when i = 0 [only when i = 0 is considered], the previous thread executes wait(), and executing wait() will make the current thread wait

Execution process of this example: Main (join()) < - thread0 (wait()) < - thread1(wait())
Only after the sleep of the main() thread ends, the subsequent thread is notified () and then ends the wait()

Conclusion: this problem is still not understood clearly. For example, which Object is the current thread wait()?
The guess is the new Domino() object, but the run method of the object is not modified by synchronized;

And thread Start () executes the method in target. What is the process?

Today, I finally compiled the source code of openjdk8. First summarize the compilation process, then learn debug jdk and continue to track the problem

Tags: Java Concurrent Programming

Posted by cnperry on Fri, 15 Apr 2022 16:04:13 +0930