在Thread.join()结束时调用notifyAll的位置

时间:2014-09-04 18:15:07

标签: java multithreading

来自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()的线程如何得到通知)

2 个答案:

答案 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对象上调用notifyAllThreadnative start实现this.notifyAll()必须这样做,即。调用native(可能在wait代码中实现)。

这也是开发人员绝对不应该在notify个实例上调用Threadjoin的原因,以免混淆这个{{1}}实现。