来自jdk 1.7.0_45 Thread.join的实例方法(long miilliseconds)通过使调用者Thread在此Thread的对象监视器上等待来工作。此外,javadoc明确指出
As a thread terminates the this.notifyAll method is invoked. It is recommended that applications not use wait, notify, or notifyAll on Thread instances.
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;
}
wai t(delay);
now = System.currentTimeMillis() - base;
}
}
}
我没有看到notifyAll()被调用,因此线程调用join()获取此Thread对象的监视器
如果我在线程t上调用t.join(0)
,那么我没有在我的run()代码中实现notifyAll()
。那么调用者线程(调用t.join()的线程如何得到通知)
答案 0 :(得分:4)
文档说:
当一个线程终止时,调用this.notifyAll方法
join方法不对通知负责,而是等待的事情。 通知将是任何JVM代码负责终止线程的工作。
答案 1 :(得分:1)
您必须先了解notify-wait mechanism。一个线程等待(在一个对象上),直到另一个线程通知它。
示例代码
// in main thread
Thread t1 = new Thread(..);
t1.start();
t1.join();
Thread#start()
的实施是native
。无论是notifyAll()
方法是突然还是正常完成,都需要实现Thread#run()
。
这是必需的,以便可以通知调用join()
的线程。
在上面的示例中,当main
线程调用join()
时,它最终会执行
wait(delay);
在Thread
引用的t1
实例上调用。这将导致main
线程阻塞,直到在同一notify
对象上调用notifyAll
或Thread
,native
start
实现this.notifyAll()
必须这样做,即。调用native
(可能在wait
代码中实现)。
这也是开发人员绝对不应该在notify
个实例上调用Thread
和join
的原因,以免混淆这个{{1}}实现。