join method example 1
Source code
import java.util.concurrent.TimeUnit; public class JoinWaitTest { private static int a = 0; private static int b = 100; public static void main(String... args) throws InterruptedException{ Thread t = new Thread(new WaitThread()); t.start(); t.join(); System.out.println("I'm waiting for WaitThread end."); System.out.println("The result is " + (a + b)); } static class WaitThread implements Runnable { @Override public void run() { try { for (int i = 1; i < 6; i++) { TimeUnit.SECONDS.sleep(1); a++; System.out.println(i); } } catch (InterruptedException e) { } } } }
results of enforcement
1
2
3
4
5
I'm waiting for WaitThread end.
The result is 105
Scene description
In many cases, the main thread generates and starts the sub thread. If there are a lot of time-consuming operations in the sub thread, the main thread usually ends before the sub thread. However, if the main thread processes other transactions, it needs to use the processing results of the sub thread, that is, the main thread needs to wait for the execution of the sub thread before ending. At this time, it needs to use join() Method.
This example is just an example, which demonstrates the above process.
join method example 2
Source code
import java.util.concurrent.TimeUnit; public class JoinTest { public static void main(String... args) throws InterruptedException { Thread jt = new Thread(new JoinThread()); Thread tt = new Thread(new TimingThread()); tt.start(); tt.join(); jt.start(); } static class JoinThread implements Runnable { @Override public void run() { System.out.println("I have waited for too long."); } } static class TimingThread implements Runnable { @Override public void run() { for (int i = 0; i < 6; i++) { try { TimeUnit.SECONDS.sleep(1); System.out.println("Sleep end!"); } catch (InterruptedException e) { } } } } }
results of enforcement
Sleep end!
Sleep end!
Sleep end!
Sleep end!
Sleep end!
Sleep end!
I have waited for too long.
Scene description
It is the same as source code example 1, except that jt thread has to wait for tt thread to finish.
Source code analysis of join method
jdk source code
/** * 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; } } }
join source code analysis without parameters 1 -- essentially calling the wait method
The join() method is essentially join(0), and the final execution code is as follows
In essence, calling code 1 is equivalent to calling code 2
Source code analysis of join with parameters
Core code
A change:
while (isAlive()) {
if (millis <= now) {
break;
}
wait(millis - now);
now = System.currentTimeMillis() - base;
}
analysis
base and now are both time. base is the time when the code is just executed, and now is the time when the code is executed. Judge whether the mills time has passed. When the time has passed, break will jump out of the code.