繁体   English   中英

Thread.join()是否释放锁? 还是继续持有它?

[英]Does Thread.join() release the lock? Or continue to hold it?

据我了解,内部obj.join()调用wait() 这意味着join()总是释放锁(因为wait()总是在被调用后释放锁)。

API文档说明

此实现使用的循环this.wait电话空调上this.isAlive 当线程终止时,将调用this.notifyAll方法。 建议应用程序不要在Thread实例上使用waitnotifynotifyAll

有人在这里join()不会释放任何锁,因为API没有明确提及它。 但是这种逻辑对我来说似乎很奇怪。

这是join()代码的主要逻辑:

 while (isAlive()) {
            wait(0);
        }

该站点进一步加剧了混乱(我认为它们是错误的):

3)的第三个区别wait()join()的方法是,当一个线程调用wait()方法,它释放了在该对象持有的任何锁wait()被调用,但调用join()方法没有按不要释放任何监视器或锁。

wait释放保留在调用了wait的对象上的监视器,但不释放任何其他监视器。

当前线程必须拥有该对象的监视器。 线程释放该监视器的所有权并等待。

换句话说,给出以下内容:

synchronized (a) {
    synchronized (b) {
        b.wait();
    }
}

b.wait()当前线程释放b的显示器,而不是a的显示器。

如果t.join()使用实施t.wait()内部,然后t的监视器被释放,同时等待,但不排除任何其它的显示器。

顺便说一句,这种join实现是泄漏抽象的情况。 如果Thread使用了private final Object monitor; 要等待,我们可以说join没有释放任何监视器,即使join内部在我们不知情的情况下使用wait 没有理由记录使用wait的实现细节,因为我们无法访问监视器,因此我们无需了解它。

我们知道join内部使用wait的原因是,最初编写该方法的人选择了我们可以访问的监视器。 这就需要揭示实施细节。 从我们的角度来看, join并不是真的应该释放监视器,而只是等待线程完成,但是选择了一个实现,这需要我们比我们应该了解的更多。

尽管@Radiodef的出色答案阐明并阐述了抽象泄漏的缺点,但以更简单的方式回答@vrinchvucz的困惑,答案是,

是的,当线程调用t.join它确实获取并释放了“ a”监视器锁定。 该监视器锁是线程t本身的监视器锁,因为Thread类上join方法的实现是通过在synchronized join方法内部使用this.wait实现的,这是@Radiodef指向的泄漏抽象问题。

因此,除非线程在调用t.join之前获取了t本身的监视器锁, t.join我们可以说在t.join调用中不会释放任何客户机/用户获得的监视器锁(因为所讨论的监视器锁与客户机/在调用t.join的线程中获取的用户代码。

这是因为正如Object#wait的文档中明确指出的那样

请注意,wait方法将当前线程放入该对象的等待集中,因此只会解锁该对象; 当线程等待时,当前线程可以在其上同步的所有其他对象保持锁定。

这就是为什么Thread#join的文档没有提及有关释放锁的任何内容,同时仍提供了有关this.wait的使用的实现细节。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM