有人可以解释 Java Thread 类中的 join 方法吗?

2022-01-22 00:00:00 multithreading synchronization java
    public final synchronized void join(long millis) throwsInterruptedException {
    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) 如何让主线程等待它完成.线程正在调用自身等待?据我了解,它必须对自身进行锁定才能调用 wait() 方法?完成后如何通知主线程?

How does wait(0) make the main thread wait until it finishes. Thread is calling wait on itself? As far as my understanding it must have a lock on itself to call wait() method? How does it notify the main thread when it finishes?

推荐答案

文档解释了逻辑:

此实现使用 this.wait 调用循环,该调用以 this.isAlive 为条件.当线程终止时,将调用 this.notifyAll 方法.建议应用程序不要在 Thread 实例上使用 waitnotifynotifyAll.

This implementation uses a loop of this.wait calls conditioned on this.isAlive. As a thread terminates the this.notifyAll method is invoked. It is recommended that applications not use wait, notify, or notifyAll on Thread instances.

所以这个实现依赖于这样一个事实:Thread 对象不仅代表一个线程,而且和Java 中的任何其他对象一样也是一个对象.因此,它继承自 Object,有自己的监视器并且可以同步,有线程 wait 在其上运行,等等.

So this implementation relies on the fact that the Thread object does not just represent a thread, but is also an object like any other object in Java. As such, it inherits from Object, has its own monitor and can be synchronized, have threads waiting on it, etc.

调用wait()方法必须自己有锁吗?

It must have a lock on itself to call wait() method?

是的.事实上,这个方法被声明为 synchronized.所以它在 Thread 实例本身上同步.一旦你进入其中,你就有了 Thread 实例的监视器.然后当 wait 被调用时,你放弃它,所以其他线程可以做同样的事情.

Yes. And indeed, this method is declared synchronized. So it synchronizes on the Thread instance itself. Once you are inside it, you have the Thread instance's monitor. Then when wait is called, you relinquish it, so other threads can do the same thing.

这可能有点令人困惑.您当前正在运行的线程是线程 A.您正在线程 B 上使用 join.这里正在同步的对象是线程 B 的实例,这会导致线程 A 等到 notifyAll 在同一个 (B) 实例上调用.

This might be a bit confusing. Your currently running thread is thread A. You are using join on thread B. The object being synchronized on here is the instance of thread B, and this causes thread A to wait until notifyAll is called on the same (B) instance.

当线程 B 完成时,它会在自己的实例上调用 notifyAll.因此,在线程 B 的实例上的 wait 中阻塞的任何线程都会收到通知.

When the thread B finishes, it calls notifyAll on its own instance. So any threads that are blocked in a wait on thread B's instance will be notified.

相关文章