当线程试图进入临界区并获得锁时,它实际上在做什么?
我问这个是因为我通常创建一个对象(对象类型),它仅用于锁定目的。 考虑以下几点:我想编写一个接受集合的方法和一个将用作锁定对象的对象,以便该方法内的整个集合操作将在关键部分内声明,该关键部分将被该给定对象锁定。
我应该使用“ref”传递锁定对象还是传递该对象的引用副本就足够了?换句话说 - 由于 lock 语句仅用于引用类型,该机制是检查引用对象的值,还是检查指针的值?因为很明显,当传递一个没有“ref”的对象时,我实际上得到了一个引用的副本,而不是引用本身。
最佳答案
这是您可以遵循的典型锁定模式。基本上,您可以创建一个锁定对象,用于锁定对关键部分的访问(正如@Hans 所说,它不保护您正在处理的对象——它只是处理锁)。
class ThreadSafe
{
static readonly object _locker = new object();
static int _val1, _val2;
static void Go()
{
lock (_locker)
{
if (_val2 != 0) Console.WriteLine (_val1 / _val2);
_val2 = 0;
}
}
}
这个例子来自Joseph Albahari's online book在线程。它很好地概述了创建 lock
语句时发生的情况,并提供了一些有关如何对其进行最佳优化的提示/技巧。强烈推荐阅读。
再一次,根据 Albahari 的说法,lock
语句在 .NET 4 中翻译为:
bool lockTaken = false;
try
{
Monitor.Enter (_locker, ref lockTaken);
// Do your stuff...
}
finally { if (lockTaken) Monitor.Exit (_locker); }
它实际上比直接 Monitor.Enter
然后在 finally
中调用 Monitor.Exit
更安全,这就是它被添加到.NET 4.
关于C# 锁定语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7057058/