C# 锁定语句

标签 c# locking mutex sync

当线程试图进入临界区并获得锁时,它实际上在做什么?

我问这个是因为我通常创建一个对象(对象类型),它仅用于锁定目的。 考虑以下几点:我想编写一个接受集合的方法和一个将用作锁定对象的对象,以便该方法内的整个集合操作将在关键部分内声明,该关键部分将被该给定对象锁定。

我应该使用“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/

相关文章:

java - Java 监视器的等待集是否优先于入口集?

c - 多线程,不能让另一个线程工作

c# - C# 生成的 Excel 工作表中的自动调整列宽

c# - 从telnet服务器C#套接字读取响应

java - 锁拆分与锁 strip 化

go - 锁定golang递归映射

rust - 如何在 Rust 中正确改变互斥体后面的向量

c# - 将 WinDbg 附加到从 HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run 登录时运行的进程?

c# - 连接到 Oracle 数据库

c# - 锁定当前线程 : Possible WTF?