1. Examples and functions of join()

1.1 the sample

1 public class Parent {3 public static void main(String[] args) {4 Child child = NEW child (); 7 child.start(); 8 // Wait for the child thread to finish before continuing 9 child.join(); 11 10}}Copy the code
1 / / the Child Thread 2 public class Child extends Thread {3 public void the run () {/ / 4... 6 5}}Copy the code

The code above shows two classes: Parent (Parent thread) and Child (Child thread).

The parent.main () method is the entry to the program, via Child Child = new Child(); Create a child thread (while the child thread is in NEW state).

Then call child.start() (child child thread state transitions to RUNNABLE);

Call child.join(), at which point the Parent thread waits for the child thread to finish running before continuing.

Below is my summary of the Java thread state transition diagram:

1.2 Functions of Join ()

Make the parent thread wait for the child thread to finish before continuing.

Let’s look at the related description in the Java 7 Concurrency Cookbook (which makes it very clear what join() does) :

Waiting for the finalization of a thread

In some situations, we will have to wait for the finalization of a thread. For example, we may have a program that will begin initializing the resources it needs before proceeding with the rest of the execution. We can run the initialization tasks as threads and wait for its finalization before continuing with the rest of the program. For this purpose, we can use the join() method of the Thread class. When we call this method using a thread object, it suspends the execution of the calling thread until the object called finishes its execution.
Copy the code
When we call this method on a thread, it suspends the calling thread until the called thread finishes executing.Copy the code

Join () in JDK 8:

1 public final void join() throws InterruptedException { 2 join(0); 3 } 4 5 public final synchronized void join(long millis) 6 throws InterruptedException { 7 long base = System.currentTimeMillis(); 8 long now = 0; 9 10 if (millis < 0) { 11 throw new IllegalArgumentException("timeout value is negative"); 12 } 13 14 if (millis == 0) { 15 while (isAlive()) { 16 wait(0); 17 } 18 } else { 19 while (isAlive()) { 20 long delay = millis - now; 21 if (delay <= 0) { 22 break; 23 } 24 wait(delay); 25 now = System.currentTimeMillis() - base; 26 } 27 } 28 } 29 30 public final synchronized void join(long millis, int nanos) 31 throws InterruptedException { 32 33 if (millis < 0) { 34 throw new IllegalArgumentException("timeout value  is negative"); 35 } 36 37 if (nanos < 0 || nanos > 999999) { 38 throw new IllegalArgumentException( 39 "nanosecond timeout value out of  range"); 40 } 41 42 if (nanos >= 500000 || (nanos ! = 0 && millis == 0)) { 43 millis++; 44 } 45 46 join(millis); 47}Copy the code

There are three overloaded versions of join() with no arguments, one argument, and two arguments:

1 public final void join() throws InterruptedException;
2 
3 public final synchronized void join(long millis) throws InterruptedException;
4 
5 public final synchronized void join(long millis, int nanos) throws InterruptedException;
Copy the code

Among them

(1) All three methods are final and cannot be overridden by subclasses.

(2) Join (long), join(long, long) is synchronized method, and the synchronized object is the current thread instance.

(2) Both the no-parameter version and the two-parameter version end up calling the one-parameter version.

(3) Join () is equivalent to join(0), which means that it keeps waiting; Join (non-0) waits for a period of time.

Join (0) calls object.wait (0), where object.wait (0) waits until notify/ interrupts.

While (isAlive()) prevents the child thread from spurious wakeup. As long as the child thread is not TERMINATED, the parent thread needs to wait.

(4) Join (), like sleep(), can be interrupted (InterrupptedException will be thrown when interrupted); The difference is that join() calls wait() internally, which sells the lock, while sleep() holds the lock.

Using the code at the beginning of this article as an example, let’s examine the code logic:

Call chain: Parent-main () -> child.join() -> child.join(0) -> child.wait(0) But you cannot enter child.join(0) because child.join(0) is a synchronous method.

If the child thread is Active, child.wait(0) is called (to prevent spurious wakeup, wait(0) needs to be placed in a while(isAlive()) loop.

Once the child thread is not Active (state TERMINATED), Child.notifyall () is called -> child.wait(0) returns -> child.join(0) returns -> child.join() returns -> Parent. Main () continues, and the child thread calls this.notify(), Child.wait (0) returns to child.join(0), child.join(0) returns to child.join(), child.join() returns to the Parent thread, and the Parent thread can continue.

3. Question other articles analyzing join() on the Internet

I think the description of many articles on the Internet has ambiguity, the following select some description for analysis, also welcome everyone to leave a message together to discuss.

A. After the child thread finishes, the main thread will wake up, and the parent thread will regain CPU execution authority and continue to run.

When the child thread terminates, this.notifyall () is called, join() is returned, and the parent thread can continue running as long as it has acquired the lock and CPU.

B. join() merges several parallel threads into a single thread.

I understand what this means, but it just makes it harder for the reader to understand.

In a program that calls the join() method, the original multiple threads are still multiple threads, and no “merge into a single thread” has occurred. What really happens is that the thread calling join() goes into TIMED_WAITING and waits until the thread to which join() belongs finishes running.

A thought: When writing technical articles, it is best to avoid using too colloquial words.

Because this kind of vocabulary is relatively ambiguous, it will make readers feel more confused or form a wrong understanding.

Mysql, Netty, Spring, thread, Spring Cloud, JVM, source code, algorithm, etc., also have a detailed learning plan map, interview questions, etc., need to obtain these contents of the friend please add Q: sample: 909038429/./* Welcome to Java chat