是否应该避免嵌套锁定请求?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了是否应该避免嵌套锁定请求?相关的知识,希望对你有一定的参考价值。

我有一个java类,它接收来自外部的输入(即同时运行的许多线程),然后将输入存储到两个循环缓冲区中。这些缓冲区协同工作以执行相同的工作,并且仅根据其优先级而不同。也就是说,缓冲区被命名为“primary”和“secondary”:当输入到达时,首先检查主缓冲区,如果它已满,则检查辅助缓冲区。即使辅助缓冲区已满,输入也会等待其中一个缓冲区中的插槽可用。我认为我可以通过首先锁定主缓冲区上的访问权限来管理并发性,并且仅在必要时请求锁定辅助缓冲区,同时仍然保持先前的锁定。我不知道为什么,但对我来说听起来很奇怪。只要它不会导致死锁或繁重的饥饿场景,同时持有两个锁是好的/安全的实践吗?

感谢您的关注。

答案

如果您不能保证始终以相同的顺序获取两个锁,则存在死锁的风险。 如果您可以保证在进入内锁时始终保持外锁,则内锁是多余的。 (*) 如果你可以保证,如果代码持有内部锁,没有其他代码会请求外部锁,那么这不会导致死锁。但是,这很脆弱,因为现在你在推理通常相当远的代码。除非存在外部锁定以确保不同时获取外部锁定,否则您将回到上述两种情况之一。

所以是的,你应该避免嵌套锁:你要么死锁,要么没用,或者你有一个脆弱的系统。

(*)这里有一个例外:如果外部锁定代码区域启动使用内部锁定坐标的线程,则不适用。 这种代码是非常罕见的,与你在实践中看到的嵌套锁方案有很大不同,我甚至不愿意将它称为嵌套锁,即使它是技术上的。

以上是关于是否应该避免嵌套锁定请求?的主要内容,如果未能解决你的问题,请参考以下文章

我是否必须锁定Blueprint实例以避免Flask中的竞争条件?

如何锁定文件并避免在写入时读取

是否有任何理由锁定队列?

具有层次锁定的 RW 锁定

我可以使用联锁操作来更新多个值以避免锁定关键部分/互斥锁吗?

CLR是否执行“锁定省略”优化?如果不是为什么不呢?