简体   繁体   English

二进制信号量 vs 可重入锁

[英]Binary Semaphore vs a ReentrantLock

I've been trying to understand Reentrant locks and Semaphores ( the nesting of Reentrant locks vs release/unlock mechanism ).我一直在尝试了解可重入锁和信号量(可重入锁与释放/解锁机制的嵌套)。

It seems that having a Semaphore requires you to write a more thoroughly tested application because the release() method does not check if the thread releasing the permit is actually holding it.似乎拥有 Semaphore 需要您编写经过更彻底测试的应用程序,因为 release() 方法不会检查释放许可的线程是否实际持有它。 When I tested my test code, I found out that this may subsequently increase the number of permits beyond the initial limit.当我测试我的测试代码时,我发现这可能会导致许可证数量增加超出初始限制。 On the other hand, if a thread is not holding a reentrant lock when it invokes the unlock method, we get an IllegalMonitorException.另一方面,如果一个线程在调用 unlock 方法时没有持有可重入锁,我们会得到一个 IllegalMonitorException。

So would it be right to say that there is no real reason ever to have a binary semaphore as everything that a binary semaphore can do can also be done by a ReentrantLock.所以说没有真正的理由拥有二进制信号量是对的,因为二进制信号量可以做的一切也可以通过 ReentrantLock 来完成。 If we use binary semaphores we would have to check the entire method call stack to see if a permit was acquired before ( also was it released too if there is a possibility of a subsequent acquire - which might block if a release does not proceed it and so on ).如果我们使用二进制信号量,我们将不得不检查整个方法调用堆栈以查看之前是否获得了许可(如果有后续获得的可能性,它是否也被释放 - 如果释放不继续,这可能会阻塞它和等等)。 Also since reentrant locks also provide one lock per object, isn't it always a better idea to prefer a reentrant lock to a binary semaphore?此外,由于可重入锁还为每个对象提供一个锁,与二进制信号量相比,更喜欢重入锁是否总是更好的主意?

I have checked a post here that talks about difference between a binary semaphore and a mutex but is there a thing like a mutex in Java?我在这里查看了一篇文章,其中讨论了二进制信号量和互斥锁之间的区别,但是在 Java 中有没有像互斥锁这样的东西?

Thanks, Chan.谢谢,陈。

PS - I had posted this question in another forum ( http://www.coderanch.com/t/615796/threads/java/reason-prefer-binary-Semaphore-Reentrant ) and I haven't received a response yet. PS - 我在另一个论坛( http://www.coderanch.com/t/615796/threads/java/reason-prefer-binary-Semaphore-Reentrant )发布了这个问题,但我还没有收到回复。 I thought I'd post it here as well to see what I can get.我想我也会把它贴在这里,看看我能得到什么。

there is no real reason ever to have a binary semaphore as everything that a binary semaphore can do can also be done by a ReentrantLock没有真正的理由拥有二进制信号量,因为二进制信号量可以做的一切也可以通过 ReentrantLock 来完成

If all you need is reentrant mutual exclusion, then yes, there is no reason to use a binary semaphore over a ReentrantLock.如果您只需要可重入互斥,那么是的,没有理由在 ReentrantLock 上使用二进制信号量。 If for any reason you need non-ownership-release semantics then obviously semaphore is your only choice.如果出于任何原因您需要非所有权释放语义,那么显然信号量是您唯一的选择。

Also since reentrant locks also provide one lock per object, isn't it always a better idea to prefer a reentrant lock to a binary semaphore?此外,由于可重入锁还为每个对象提供一个锁,与二进制信号量相比,更喜欢重入锁是否总是更好的主意?

It depends on the need.这取决于需要。 Like previously explained, if you need a simple mutex, then don't choose a semaphore.如前所述,如果您需要一个简单的互斥锁,则不要选择信号量。 If more than one thread (but a limited number) can enter a critical section you can do this through either thread-confinement or a semaphore.如果多个线程(但数量有限)可以进入临界区,您可以通过线程限制或信号量来实现。

I have checked a post here that talks about difference between a binary semaphore and a mutex but is there a thing like a mutex in Java?我在这里查看了一篇文章,其中讨论了二进制信号量和互斥锁之间的区别,但是在 Java 中有没有像互斥锁这样的东西?

ReentrantLock and synchronized are examples of mutexes in Java. ReentrantLocksynchronized是 Java 中互斥锁的例子。

I will not explain re-entrant locks since John has already given a good explanation above and its an example of mutex in java along with Synchronized keyword.我不会解释可重入锁,因为 John 已经在上面给出了很好的解释,它是 Java 中互斥锁和 Synchronized 关键字的示例。

However, if for any reason, you would like to have a better control over the locking mechanism, Semaphore can become handy.但是,如果出于任何原因,您想更好地控制锁定机制,信号量可以变得很方便。 This means, your code will have to remain in-charge of who called acquire() and who called release() since Semaphore by nature is blind to it, all it cares is permit becomes available.这意味着,您的代码必须继续负责谁调用了acquire() 和谁调用了release(),因为信号量本质上对它视而不见,它所关心的只是允许可用。

Another approach of your own mutex implementation using java is LockSupport.使用 java 实现自己的互斥锁的另一种方法是 LockSupport。 It works a bit like Semaphore but has a timeout on the permit, using park() function and only supports one permit at a time unlike Semaphores which support multiple of them.它的工作方式有点像信号量,但在许可上有一个超时,使用 park() 函数,并且一次只支持一个许可,而信号量则支持多个许可。

There are some small differences between Semaphore and reenterant lock.信号量和重入锁之间有一些小的区别。

  • Semaphore may be released by another thread.信号量可能被另一个线程释放。 Semaphore's javadoc states that such behavior may be useful in some specialized contexts like deadlock recovery. Semaphore 的 javadoc 声明这种行为可能在一些特殊的上下文中很有用,比如死锁恢复。 So it should be a really specialized contexts.所以它应该是一个真正专门的上下文。
  • Also binary semaphores are not reenterant.二进制信号量也不是可重入的。 You cannot acquire a binary semaphore second time in a same thread.您不能在同一线程中第二次获取二进制信号量。 It will lead to a deadlock (deadlocking thread with itself!) and you may need some means of already mentioned deadlock recovery它会导致死锁(使线程与自身发生死锁!)并且您可能需要一些已经提到的死锁恢复方法

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM