#unity/日常积累 # lock 语句 - 确保对共享资源的独占访问权限 - 项目 - 2024/04/02 - 3 个参与者 反馈 ## 本文内容 1. [准则](https://learn.microsoft.com/zh-cn/dotnet/csharp/language-reference/statements/lock#guidelines) 2. [示例](https://learn.microsoft.com/zh-cn/dotnet/csharp/language-reference/statements/lock#example) 3. [C# 语言规范](https://learn.microsoft.com/zh-cn/dotnet/csharp/language-reference/statements/lock#c-language-specification) 4. [另请参阅](https://learn.microsoft.com/zh-cn/dotnet/csharp/language-reference/statements/lock#see-also) `lock` 语句获取给定对象的互斥 lock,执行语句块,然后释放 lock。 持有 lock 时,持有 lock 的线程可以再次获取并释放 lock。 阻止任何其他线程获取 lock 并等待释放 lock。 `lock` 语句可确保在任何时候最多只有一个线程执行其主体。 `lock` 语句具有以下格式 ``` cs lock (x) { // Your code... } ``` 其中 `x` 是[引用类型](https://learn.microsoft.com/zh-cn/dotnet/csharp/language-reference/keywords/reference-types)的表达式。 它完全等同于 ``` cs 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` 语句](https://learn.microsoft.com/zh-cn/dotnet/csharp/language-reference/statements/exception-handling-statements#the-try-finally-statement),因此即使在 `lock` 语句的正文中引发异常,也会释放 lock。 在 `lock` 语句的正文中不能使用 [`await` 表达式](https://learn.microsoft.com/zh-cn/dotnet/csharp/language-reference/operators/await)。 [](https://learn.microsoft.com/zh-cn/dotnet/csharp/language-reference/statements/lock#guidelines) ## 准则 当同步对共享资源的线程访问时,请锁定专用对象实例(例如,`private readonly object balanceLock = new object();`)或另一个不太可能被代码无关部分用作 lock 对象的实例。 避免对不同的共享资源使用相同的 lock 对象实例,因为这可能导致死锁或锁争用。 具体而言,请避免将以下实例用作 lock 对象: - `this`(调用方可能将其用作 lock)。 - [Type](https://learn.microsoft.com/zh-cn/dotnet/api/system.type) 实例(可以通过 [typeof](https://learn.microsoft.com/zh-cn/dotnet/csharp/language-reference/operators/type-testing-and-cast#typeof-operator) 运算符或反射获取)。 - 字符串实例,包括字符串字面量,(这些可能是[暂存的](https://learn.microsoft.com/zh-cn/dotnet/api/system.string.intern#remarks))。 尽可能缩短持有锁的时间,以减少锁争用。