#unity/日常积累

lock 语句 - 确保对共享资源的独占访问权限

  • 项目
  • 2024/04/02
  • 3 个参与者

反馈

本文内容

  1. 准则
  2. 示例
  3. C# 语言规范
  4. 另请参阅

lock 语句获取给定对象的互斥 lock,执行语句块,然后释放 lock。 持有 lock 时,持有 lock 的线程可以再次获取并释放 lock。 阻止任何其他线程获取 lock 并等待释放 lock。 lock 语句可确保在任何时候最多只有一个线程执行其主体。

lock 语句具有以下格式

1
2
3
4
lock (x)
{
    // Your code...
}

其中 x 是引用类型的表达式。 它完全等同于

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
object __lockObj = x;
bool __lockWasTaken = false;
try
{
    System.Threading.Monitor.Enter(__lockObj, ref __lockWasTaken);
    // Your code...
}
finally
{
    if (__lockWasTaken) System.Threading.Monitor.Exit(__lockObj);
}

由于该代码使用 try-finally 语句,因此即使在 lock 语句的正文中引发异常,也会释放 lock。

在 lock 语句的正文中不能使用 await 表达式

准则

当同步对共享资源的线程访问时,请锁定专用对象实例(例如,private readonly object balanceLock = new object();)或另一个不太可能被代码无关部分用作 lock 对象的实例。 避免对不同的共享资源使用相同的 lock 对象实例,因为这可能导致死锁或锁争用。 具体而言,请避免将以下实例用作 lock 对象:

  • this(调用方可能将其用作 lock)。
  • Type 实例(可以通过 typeof 运算符或反射获取)。
  • 字符串实例,包括字符串字面量,(这些可能是暂存的)。

尽可能缩短持有锁的时间,以减少锁争用。