[英]Does Thread.join() release the lock? Or continue to hold it?
As I understand it, internally obj.join()
calls wait()
. 据我了解,内部
obj.join()
调用wait()
。 This means that join()
always releases the lock (because wait()
always releases the lock after being called). 这意味着
join()
总是释放锁(因为wait()
总是在被调用后释放锁)。
The API doc explains : API文档说明 :
This implementation uses a loop of
this.wait
calls conditioned onthis.isAlive
.此实现使用的循环
this.wait
电话空调上this.isAlive
。 As a thread terminates thethis.notifyAll
method is invoked.当线程终止时,将调用
this.notifyAll
方法。 It is recommended that applications not usewait
,notify
, ornotifyAll
onThread
instances.建议应用程序不要在
Thread
实例上使用wait
,notify
或notifyAll
。
People here on SO say that join()
does not release any lock because the API does not mention it explicitly. 有人在这里说
join()
不会释放任何锁,因为API没有明确提及它。 But this logic seems strange to me. 但是这种逻辑对我来说似乎很奇怪。
Here is the main logic from join()
's code: 这是
join()
代码的主要逻辑:
while (isAlive()) {
wait(0);
}
This site further adds to the confusion (I think they are mistaken): 该站点进一步加剧了混乱(我认为它们是错误的):
3) The third difference between the
wait()
andjoin()
methods is that when a thread calls thewait()
method it releases any lock held for the object on whichwait()
is called, but calling thejoin()
method doesn't release any monitor or lock.3)的第三个区别
wait()
和join()
的方法是,当一个线程调用wait()
方法,它释放了在该对象持有的任何锁wait()
被调用,但调用join()
方法没有按不要释放任何监视器或锁。
wait
releases the monitor held on the object which wait
is invoked on, but not any other monitors. wait
释放保留在调用了wait
的对象上的监视器,但不释放任何其他监视器。
The current thread must own this object's monitor.
当前线程必须拥有该对象的监视器。 The thread releases ownership of this monitor and waits [...].
线程释放该监视器的所有权并等待。
In other words, given the following: 换句话说,给出以下内容:
synchronized (a) {
synchronized (b) {
b.wait();
}
}
At b.wait()
, the current thread releases b
's monitor, but not a
's monitor. 在
b.wait()
当前线程释放b
的显示器,而不是a
的显示器。
If t.join()
is implemented using t.wait()
internally, then t
's monitor is released while waiting, but not any other monitor. 如果
t.join()
使用实施t.wait()
内部,然后t
的监视器被释放,同时等待,但不排除任何其它的显示器。
This join
implementation is a case of leaky abstraction , by the way. 顺便说一句,这种
join
实现是泄漏抽象的情况。 If Thread
used a private final Object monitor;
如果
Thread
使用了private final Object monitor;
to wait on instead, we could say that join
released no monitors, even if it used wait
internally without us knowing. 要等待,我们可以说
join
没有释放任何监视器,即使join
内部在我们不知情的情况下使用wait
。 There would be no reason to document the implementation detail of using wait
, because the monitor would be inaccessible to us, so we would not need to know about it. 没有理由记录使用
wait
的实现细节,因为我们无法访问监视器,因此我们无需了解它。
The reason that we know join
uses wait
internally is that the people who originally wrote the method chose a monitor which is accessible to us. 我们知道
join
内部使用wait
的原因是,最初编写该方法的人选择了我们可以访问的监视器。 This created the need to reveal the implementation details. 这就需要揭示实施细节。
join
is not really supposed to release monitors from our perspective, just wait for a thread to complete, but an implementation was chosen which required us to know more about it than we should. 从我们的角度来看,
join
并不是真的应该释放监视器,而只是等待线程完成,但是选择了一个实现,这需要我们比我们应该了解的更多。
Though the excellent answer from @Radiodef clarifies & elaborates the leaky abstraction shortcoming, in simpler terms to answer @vrinchvucz confusion the answer is, 尽管@Radiodef的出色答案阐明并阐述了抽象泄漏的缺点,但以更简单的方式回答@vrinchvucz的困惑,答案是,
Yes, when a thread invokes t.join
it does acquire and release 'a' monitor lock. 是的,当线程调用
t.join
它确实获取并释放了“ a”监视器锁定。 That monitor lock is that of the thread t
itself since the implementation of join method on Thread class implemented it by using this.wait
inside of the synchronized
join
method which is the leaky abstraction issue that @Radiodef points to. 该监视器锁是线程
t
本身的监视器锁,因为Thread类上join方法的实现是通过在synchronized
join
方法内部使用this.wait
实现的,这是@Radiodef指向的泄漏抽象问题。
Thus unless the thread acquires the monitor lock of t
itself before it invokes t.join
we can say that NO client/user acquired monitor locks are released in the t.join
invocation (because the monitor lock in question is NOT any that the client/user code acquired in the thread that invoked t.join
). 因此,除非线程在调用
t.join
之前获取了t
本身的监视器锁, t.join
我们可以说在t.join
调用中不会释放任何客户机/用户获得的监视器锁(因为所讨论的监视器锁与客户机/在调用t.join
的线程中获取的用户代码。
This since as clearly stated in the docs for Object#wait 这是因为正如Object#wait的文档中明确指出的那样
Note that the wait method, as it places the current thread into the wait set for this object, unlocks only this object;
请注意,wait方法将当前线程放入该对象的等待集中,因此只会解锁该对象; any other objects on which the current thread may be synchronized remain locked while the thread waits.
当线程等待时,当前线程可以在其上同步的所有其他对象保持锁定。
Which is why the docs for Thread#join
does not mention anything about locks being released while still giving the implementation details regarding the use of this.wait
. 这就是为什么
Thread#join
的文档没有提及有关释放锁的任何内容,同时仍提供了有关this.wait
的使用的实现细节。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.