java 二进制信号量与 ReentrantLock

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17683575/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-01 14:39:36  来源:igfitidea点击:

Binary Semaphore vs a ReentrantLock

javamultithreadingsemaphore

提问by Chan

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. 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.

似乎拥有 Semaphore 需要您编写经过更彻底测试的应用程序,因为 release() 方法不会检查释放许可的线程是否实际持有它。当我测试我的测试代码时,我发现这可能会导致许可证数量增加超出初始限制。另一方面,如果一个线程在调用 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. 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?

所以说没有真正的理由拥有二进制信号量是对的,因为二进制信号量可以做的一切也可以通过 ReentrantLock 来完成。如果我们使用二进制信号量,我们将不得不检查整个方法调用堆栈,以查看之前是否获得了许可(如果有后续获得的可能性,它是否也被释放了——如果释放不继续,这可能会阻塞它和很快 )。此外,由于可重入锁还为每个对象提供一个锁,与二进制信号量相比,更喜欢重入锁是否总是更好的主意?

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.

谢谢,陈。

P.S - 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. I thought I'd post it here as well to see what I can get.

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

采纳答案by John Vint

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. If for any reason you need non-ownership-release semantics then obviously semaphore is your only choice.

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

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 中有没有像互斥锁这样的东西?

ReentrantLockand synchronizedare examples of mutexes in Java.

ReentrantLocksynchronized是 Java 中互斥锁的例子。

回答by Ashley

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. 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.

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

回答by Ramesh Papaganti

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. 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
  • 信号量可能被另一个线程释放。Semaphore 的 javadoc 声明这种行为在一些特殊的上下文中可能很有用,比如死锁恢复。所以它应该是一个真正专门的上下文。
  • 二进制信号量也不是可重入的。您不能在同一线程中第二次获取二进制信号量。它会导致死锁(使线程与自身发生死锁!)并且您可能需要一些已经提到的死锁恢复方法