Let’s look at a case: Xiao Ming and his mother prepare to cook, Xiao Ming is responsible for buying food, and his mother is responsible for cooking. The premise of cooking is that Xiao Ming can’t cook until he comes back from buying food.
In the usual way, we wrote:
// omit try catch catch
new Thread(() -> {
Thread.sleep(6 _000);
System.out.println("Back from shopping!");
}, "Xiao Ming").start();
new Thread(() -> {
Thread.sleep(5 _000);
System.out.println("Dinner is ready!);
}, "Mother").start();
Copy the code
The actual result:
What happened? Oh, it turned out that our program was executed asynchronously. There was no connection between Xiao Ming and his mother, and the program was executed separately, which caused the above error.
How to solve this problem, please take a look at the following explanation…
The process here is called synchronization, so there are many methods to achieve synchronization, but we will not explain here, we use join to achieve this function……
Thread xiaoMing = new Thread(() -> {
try {
Thread.sleep(4 _000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Back from shopping!");
}, "Xiao Ming");
xiaoMing.start();
xiaoMing.join();
try {
Thread.sleep(3 _000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Mother, dinner is ready!");
Copy the code
Running results:
The principle of
The join() method has two overloaded methods,
1: join(long millis) –> indicates that the main thread is ready to execute if it has not finished executing after millis milliseconds.
Join (long millis, int nanos) –> join(long millis, int nanos) –> join(long millis, int nanos) –>
Note: If no parameter is passed, the default parameter is 0
Join the source code
public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis(); // Get the current time
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) { // When the join parameter is 0, the wait method is called to wait indefinitely
while (isAlive()) {
wait(0); }}else { // If the argument is passed, it will not wait indefinitely
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break; } wait(delay); now = System.currentTimeMillis() - base; }}}Copy the code
Join () is a synchronized method that calls wait(). The purpose of this procedure is to make the thread holding the lock wait. Who holds the lock? The main thread is waited () because the main thread called threada.join (), which is equivalent to writing a block of synchronized code in the threada.join () code block. The JVM then calls Lock. notify_all(thread) after the child thread threadA completes execution; Waking the thread that holds the object lock, the main thread, continues execution.