[英]Does Thread.join() release the lock? Or continue to hold it?
据我了解,内部obj.join()
调用wait()
。 这意味着join()
总是释放锁(因为wait()
总是在被调用后释放锁)。
API文档说明 :
此实现使用的循环
this.wait
电话空调上this.isAlive
。 当线程终止时,将调用this.notifyAll
方法。 建议应用程序不要在Thread
实例上使用wait
,notify
或notifyAll
。
有人在这里说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.