C# 锁定语句
当一个线程尝试进入临界区并获取锁时,它实际上在做什么?
我问这个问题是因为我通常创建一个对象(对象类型),该对象仅用于锁定目的。 考虑以下内容:我想编写一个接受集合的方法,以及一个用作锁定对象的对象,因此该方法内的整个集合操作将在关键部分中声明,该关键部分将由该给定对象锁定。
我应该使用“ref”传递该锁定对象还是传递该对象的引用副本就足够了?换句话说,由于 lock 语句仅与引用类型一起使用,因此该机制是否检查引用对象的值,还是检查指针的值?因为显然,当传递一个没有“ref”的对象时,我实际上得到了引用的副本,而不是引用本身。
When a thread tries to enter a critical section and obtain a lock, what is it actually doing?
I'm asking this because I usually create an object (of type object) which will serve for locking purposes only.
Consider the following: I want to write a method which accepts a collection, and an object which will serve as the locking object so the whole collection manipulation inside that method will be declared inside the critical section which will be locked by that given object.
Should I pass that locking object using "ref" or is passing a reference copy of that object is enough? In other words - since the lock statement is used with reference types only, does the mechanism check the value of the referenced object, or does it check the pointer's value? because obviously, when passing an object without "ref", I actually get a copy of the reference, and not the reference itself.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这是您可以遵循的典型锁定模式。基本上,您可以创建一个锁定对象,用于锁定对关键部分的访问(正如 @Hans 所说,它并不保护您正在处理的对象 - 它只是处理锁)。
此示例来自 Joseph Albahari 的有关线程的在线书籍。它很好地概述了创建
lock
语句时发生的情况,以及有关如何对其进行最佳优化的一些提示/技巧。绝对强烈推荐阅读。根据 Albahari 的说法,
lock
语句在 .NET 4 中翻译为:它实际上比直接使用
Monitor.Enter
然后调用Monitor.Exit
更安全> 在您的finally
中,这就是它被添加到 .NET 4 中的原因。Here's a typical pattern that you can follow for locking. Basically, you can create a locking object that is used to lock access to your critical section (which, as @Hans said, is not protecting the object that you're working on -- it just handles the lock).
This example was from Joseph Albahari's online book on threading. It provides an excellent overview of what's going on when you create a
lock
statement and some tips/tricks on how to best optimize for it. Definitely highly recommended reading.Per Albahari, again, the
lock
statement translates in .NET 4 as:It's actually safer than a straight
Monitor.Enter
and then callingMonitor.Exit
in yourfinally
, which is why it was added in .NET 4.无需传递
ref
即可锁定对象
。lock
实际上做的是,调用Monitor.Enter 位于开头该块和 Monitor.Exit 退出时。
希望这有帮助。
It's enough to lock the
object
without passingref
. Whatlock
actually does is, callMonitor.Enter on the beginning of the block and Monitor.Exit on exit.
Hope this helps.
MSDN 这里说关于锁定
因此您不需要将其作为
ref
传递,简单的按引用传递即可。这意味着它与引用或指针无关,而是与引用指向的实际对象有关, lock 请参阅 this 问题的答案,其中显示
“lock 语句由 C# 翻译”至以下内容:”
MSDN says here about lock
which means it's not about the reference or pointer it is about the actual object which is pointed by the reference so you won't need to pass as
ref
simple pass by reference will workRegarding what actually happens inside the lock see answer to this question which says
"The lock statement is translated by C# to the following:"
可能两者都不是。如果您有一些非线程安全的资源,最好的选择通常是仅从一个类直接访问该资源,该类具有一个锁对象作为字段(或者您可以直接锁定该资源)。如果您将锁对象传递给其他人,则很难确保代码仍然可以正常工作,例如,锁定是在应该完成的时候完成的,并且没有死锁。
但是,如果您确实想传递锁对象,则不需要使用
ref
,正如其他人指出的那样。锁定是在对象的实例上完成的,而不是在包含对其引用的变量上完成的。Probably neither. If you have some resource that is not thread-safe, the best option usually is to access that resource directly only from one class, which has a lock object as a field (or you can lock directly on the resource). If you pass the lock object to others, it's hard to make sure that the code will still work properly, e.g. locking is done when it should and there are no deadlocks.
But if you really want to pass the lock object, you don't need to use
ref
, as others have pointed out. Locking is done on the instance of the object, not on the variable containing reference to it.