如何在没有排他锁的线程中使用监视器?

Posted

技术标签:

【中文标题】如何在没有排他锁的线程中使用监视器?【英文标题】:How to use Monitor in threading without exclusive lock? 【发布时间】:2021-11-29 03:52:21 【问题描述】:

我有一个 C#/.Net 应用程序。

我使用Monitor.EnterMonitor.Exit 来获取对某个对象的独占访问以同步线程。

我有一个特定的情况,线程 1 应该获得对某个对象的独占访问权。另一个线程 2 的行为应该如下:我没有对对象的排他锁,它应该继续而不获取排他锁。我已经有一个独占锁被另一个线程获取了,它应该等到它被释放。

我一直在查看文档here。

但我找不到执行此操作的任何函数。

请问可以吗?

【问题讨论】:

ReaderWriterLockSlim 的行为就像我想的那样。 您是否尝试实现某种线程安全初始化? 【参考方案1】:

所以:

如果对象当前被锁定,您希望等待它被释放,但不要获得锁定 如果对象当前未锁定,您希望继续而不持有锁定

我相信这可以通过以下方式实现:

lock (theThing) 

这获取和释放,其语义与不获取锁相同,而是等待任何持有它的人。

请注意,您提出的问题本质上存在竞争条件,就好像您没有获得锁定一样:在您检查后其他人可以。我们只要这样就可以了。

Monitor 上还有无数的方法用于其他场景,通常与try/finally 混合使用 - 特别是,具有零超时的TryEnter 可用于“如果你立即取锁”可以,但如果不能,请不要等待”。

不过,ManualResetEvent 也可能值得调查。

【讨论】:

以上是关于如何在没有排他锁的线程中使用监视器?的主要内容,如果未能解决你的问题,请参考以下文章

测量线程锁定监视器的时间

锁的内存语义

线程共享数据的安全问题

java多线程学习之——多线程中几种释放锁和不释放锁的操作

ReentrantLock

C# 线程同步之排它锁/Monitor监视器类