Binary Semaphore vs ReentrantLock

我一直在努力了解Reentrant锁和信号量(Reentrant锁与释放/解锁机制的嵌套)。

似乎有一个信号量要求你编写一个更彻底测试的应用程序,因为release()方法不检查释放许可证的线程是否实际上持有它。 当我测试我的测试代码时,我发现这可能随后增加超过初始限制的许可数量。 另一方面,如果一个线程在调用unlock方法时没有持有重入锁,我们会得到一个IllegalMonitorException。

所以说没有真正的理由拥有二进制信号量是正确的,因为二进制信号量可以做的一切也可以由ReentrantLock完成。 如果我们使用二进制信号量,我们必须检查整个方法调用堆栈以查看之前是否获得了许可证(如果有可能进行后续获取,它也会被释放 – 如果某个版本没有继续获取它可能会阻止它等等)。 此外,由于重入锁也为每个对象提供一个锁,因此更喜欢将重入锁定为二进制信号量并不总是更好吗?

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

谢谢,陈。

PS – 我在另一个论坛( http://www.coderanch.com/t/615796/threads/java/reason-prefer-binary-Semaphore-Reentrant )发布了这个问题,但我还没有收到回复。 我以为我也会在这里发布,看看我能得到什么。

没有真正的理由拥有二进制信号量,因为二进制信号量可以做的一切也可以通过ReentrantLock来完成

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

此外,由于重入锁也为每个对象提供一个锁,因此更喜欢将重入锁定为二进制信号量并不总是更好吗?

这取决于需要。 像之前解释的那样,如果你需要一个简单的互斥锁,那就不要选择一个信号量。 如果多个线程(但数量有限)可以进入临界区,则可以通过线程限制或信号量来执行此操作。

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

ReentrantLocksynchronized是Java中互斥锁的示例。

我不会解释重入锁定,因为John已经在上面给出了一个很好的解释,并且它是java中的互斥锁示例以及Synchronized关键字。

但是,如果出于任何原因,您希望更好地控制锁定机制,Semaphore可以变得方便。 这意味着,你的代码将不得不继续负责谁调用acquire()和谁调用release(),因为Semaphore本质上是盲目的,所有它关心的是许可变得可用。

使用java的自己的互斥体实现的另一种方法是LockSupport。 它的工作方式有点像信号量,但在许可证上有一个超时,使用park()函数,并且一次只支持一个许可证,不像支持多个信号量的信号量。