当主线程调用子线程的join方法时,主线程进入wait,等待子线程结束或者超过等待时间,然后主线程和子线程又进入了各自的抢占模式。
public class TestJoin implements Runnable { @Override public void run() { // synchronized (currentThread()) { for (int i = 1; i <= 5; i++) { try { sleep(1000);//睡眠5秒,循环是为了方便输出信息 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("睡眠" + i); } System.out.println("TestJoin finished");//t线程结束 } //} public static void main(String[] sure) throws InterruptedException { Thread t = new Thread(new TestJoin()); long start = System.currentTimeMillis(); t.start(); t.join(3000);//等待线程t 3000毫秒 Long interval = System.currentTimeMillis()-start; System.out.println("Main finished after " + interval);//打印主线程结束 } }
可以看到,主线程如果是t.join(3000);则先子线程会打印出3次睡眠,然后主线程等到3000秒超时后继续执行。
如果调用t.join(),不给超时间的话,则主线程会一直等待子线程结束,再继续执行。
下面是join的源码,可以看到写的很明白了“A timeout of {@code 0} means to wait forever.”
/** * 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; } } }
同时看看wait(0);是怎么处理的:
public final native void wait(long timeout) throws InterruptedException;
在方法wait的注解上有这么一句话解释了如果wait(0)那就一直等着被notify,不会超时。
If
* {@code timeout} is zero, however, then real time is not taken into
* consideration and the thread simply waits until notified.
* </ul>
* {@code timeout} is zero, however, then real time is not taken into
* consideration and the thread simply waits until notified.
* </ul>