有人能解释一下Java线程类中的连接方法吗? public final synchronized void join(长毫秒)throwsInterruptedException{ 长基=System.currentTimeMillis(); long now=0; 如果(毫秒

有人能解释一下Java线程类中的连接方法吗? public final synchronized void join(长毫秒)throwsInterruptedException{ 长基=System.currentTimeMillis(); long now=0; 如果(毫秒,java,multithreading,synchronization,Java,Multithreading,Synchronization,obj.wait()导致当前线程休眠,直到另一个线程调用obj.notify() t、 join()-使当前线程等待线程“t”完成说明了逻辑: 此实现使用This.wait循环调用This.isAlive。当线程终止This时,将调用notifyAll方法。建议应用程序不要在thread实例上使用wait、notify或notifyAll 因此,这个实现依赖于这样一个事实:线程对象不仅表示线程,而且与Java中的任何其他对象一样,也是一个对象。因此,它继承自对象,有自己的监视器,可以同步,让线程

obj.wait()导致当前线程休眠,直到另一个线程调用obj.notify()

t、 join()-使当前线程等待线程“t”完成

说明了逻辑:

此实现使用
This.wait
循环调用
This.isAlive
。当线程终止
This时,将调用notifyAll
方法。建议应用程序不要在
thread
实例上使用
wait
notify
notifyAll

因此,这个实现依赖于这样一个事实:
线程
对象不仅表示线程,而且与Java中的任何其他对象一样,也是一个对象。因此,它继承自
对象
,有自己的监视器,可以同步,让线程等待等等

它自身必须有一个锁才能调用
wait()
方法

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

这可能有点混乱。您当前运行的线程是线程a。您正在线程B上使用
join
。此处正在同步的对象是线程B的实例,这会导致线程a等待,直到在同一(B)实例上调用
notifyAll

当线程B完成时,它在自己的实例上调用
notifyAll
。因此,在线程B的实例上被
wait
阻塞的所有线程都将被通知

就我所知,调用wait()方法必须有自身的锁

不是在自身上,而是在
线程
对象上。调用方在
线程
对象上有一个锁。请注意,
t.join()
是一个
同步的
方法

当它完成时,它如何通知主线程

不要被
线程
和线程之间的差异弄糊涂。
线程
实例是一个堆对象,程序使用它来启动和管理代码中执行线程的生命周期。它的方法通常由其他线程调用,而不是由它正在管理的线程调用

如果线程A调用
t.join()

请记住,在每个
t.wait()
调用中,锁被释放,然后在wait()返回之前重新获取


在由
t
管理的线程中,它所做的最后一件事是,它将
t
的状态设置为
终止
,然后调用
t.notify()
。这将唤醒线程A。

,这确实令人困惑……另一个问题:
while(isAlive()){wait(0);}
在这里调用wait()有什么好处?在while循环中忙着等待而不等待(0)也可以,也许吧?通知thead A的人是谁?忙着等待永远都不好。当它完成时,通知线程A的人是线程B。
    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;
        }
    }
}