【发布时间】:2017-10-23 10:22:58
【问题描述】:
我正在阅读有关内在锁的可重入性并发现我无法理解的语句:
如果同一个线程再次获得锁,则计数增加,当拥有线程退出同步块时,计数减少。当计数为零时,锁被释放。
当线程已经持有锁(计数已设置为 1)时,增加计数的目的是什么?这个计数会影响除锁实现之外的其他方面吗?
以下示例在父方法中给出了等于 2 的计数。我说的对吗?
class A {
void a() {
synchronized (this) {
// 2 ?
}
}
}
class B extends A {
void b() {
// 0
synchronized (this) {
// 1
a();
}
}
}
有没有办法以编程方式获取此计数?
编辑:
我知道为什么我们需要增加/减少计数。我想我们可以检查Thread.holdsLock,如果它是真的,不增加就继续。但是在退出“内部”同步块的过程中,我们不知道当前同步块是否是“最外层”。因此,我们不知道什么时候应该释放锁。
谢谢你们。
【问题讨论】:
-
"目的是什么" 那么,当你到了在
a()中释放锁的地步时,如何知道是否“真正”释放锁,或者是否还有其他东西抓住锁?如中,如何知道是直接调用a(),还是通过b()? -
@AndyTurner,“如何知道
a()是直接调用的,还是通过b()调用的”——这就是重点,但计数也没有提供此类信息。 -
@AndyTurner,当计数为 0 时,我们“真的”释放了锁。“如果还有其他东西还在持有”——没有人可以在我们持有锁的时候持有它,可以吗?
-
嗯,你不知道你是调用了 a 还是 b,这是真的。但是同步不需要:它只需要知道在
a()中同步块的末尾是否释放监视器。如果直接调用a(),它应该;如果它是通过b()间接调用的,则不应。除了在进入同步块时增加计数器并在退出同步块时减少计数器之外,你能想出另一种方法来区分吗?
标签: java multithreading concurrency locking