探究
public static void main(String[] args) throws Exception {
Thread.currentThread().join();
System.out.println("main thread exit.");
}
为了了解问题本质,我们跟进去代码看看,线程的join方法如下:
public final void join() throws InterruptedException {
join(0);
}
再继续跟:
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方法最终是待用了wait(0);这行代码,而wait方法是本地方法.
根据wait的方法定义,有以下几点逐一说明:
wait()方法在Object类定义,调用时会获取该对象上的监视器,因此必须在同步代码块上调用.从代码来看`public final synchronized void join(long millis)
throws InterruptedException`,因此调用wait方法后,实际上是获取了当前对象(根据调试查看到是main线程)的监视器.
根据wait方法的定义,它只在在如下几种情况才会被唤醒,否则将一直等待:
- Some other thread invokes the {@code notify} method for this
object and thread T happens to be arbitrarily chosen as
the thread to be awakened.
- Some other thread invokes the {@code notifyAll} method for this
object.
- Some other thread {@linkplain Thread#interrupt() interrupts}
thread T.
- The specified amount of real time has elapsed, more or less. If
{@code timeout} is zero, however, then real time is not taken into
consideration and the thread simply waits until notified.
总结
因此,回答你的问题就是,join方法实质是调用了wait方法.wait方法调用后阻塞(我不认为这是阻塞)在当前线程(main线程上),根据wait的定义,不调用notify,notifyAll,interrupt以及超时机制(本例调用的是wait(0),故不存在这种情况),那么线程将一直处于等待状态,故一直不会退出。