二进制信号量与ReentrantLock


问题内容

我一直在尝试了解可重入锁和信号量(可重入锁的嵌套与释放/解锁机制)。

似乎拥有信号量需要您编写一个经过更彻底测试的应用程序,因为release()方法不会检查释放许可的线程是否实际上持有它。测试我的测试代码时,我发现这可能会随后使许可数量超出初始限制。另一方面,如果线程在调用unlock方法时未持有可重入锁,则将收到IllegalMonitorException。

因此,可以说没有真正的理由拥有二进制信号量,因为二进制信号量可以做的所有事情也可以由ReentrantLock完成。如果我们使用二进制信号量,我们将必须检查整个方法调用堆栈,以查看之前是否已获得许可(如果还有后续获取的可能性,许可是否也会被释放-
如果释放未进行,则许可可能会阻塞,并且等等)。另外,由于可重入锁还为每个对象提供一个锁,所以优先选择可重入锁而不是二进制信号量总是更好的主意吗?

我在这里检查了一篇文章,该文章讨论了二进制信号量和互斥锁之间的区别,但是在Java中是否有像互斥锁这样的东西?

谢谢陈

PS-我已经在另一个论坛(http://www.coderanch.com/t/615796/threads/java/reason-prefer-
binary-Semaphore-
Reentrant
)上发布了此问题,但尚未收到任何回复。我以为我也会在这里张贴它,看看我能得到什么。


问题答案:

没有真正的理由拥有二进制信号量,因为二进制信号量可以做的所有事情也可以由ReentrantLock完成

如果您所需要的只是可重入互斥,那么是的,没有理由在ReentrantLock上使用二进制信号量。如果出于任何原因需要非所有权释放语义,那么显然信号灯是您唯一的选择。

另外,由于可重入锁还为每个对象提供一个锁,所以优先选择可重入锁而不是二进制信号量总是更好的主意吗?

这取决于需要。如前所述,如果您需要一个简单的互斥量,则不要选择信号量。如果一个以上的线程(但数量有限)可以进入关键部分,则可以通过线程限制或信号量来执行此操作。

我在这里检查了一篇文章,该文章讨论了二进制信号量和互斥锁之间的区别,但是在Java中是否有像互斥锁这样的东西?

ReentrantLocksynchronized在Java互斥的例子。