C# lock用法
时间: 2025-07-01 12:52:02 浏览: 20
### C# 中 `lock` 关键字的使用方法
在 C# 编程中,`lock` 是一种用于确保多线程环境下的线程安全的关键字。它通过锁定一个特定的对象来阻止其他线程在同一时刻访问由该对象保护的代码区域[^1]。
#### 基本语法
以下是 `lock` 的典型用法:
```csharp
private static readonly object _lock = new object();
public void AccessSharedResource()
{
lock (_lock)
{
// 对共享资源的操作
}
}
```
在此示例中,`_lock` 是一个私有、只读的对象实例,专门用来作为锁目标。只有拥有此对象锁的线程才能进入 `lock` 代码块,其余线程会被阻塞直至锁被释放[^2]。
---
#### 示例:计数器的线程安全实现
下面展示了一个简单的线程安全计数器的例子:
```csharp
class Counter
{
private int _count = 0;
private readonly object _lockObject = new object();
public void Increment()
{
lock (_lockObject)
{
_count++;
}
}
public int GetCount()
{
lock (_lockObject)
{
return _count;
}
}
}
```
在这个例子中,无论多少个线程同时调用了 `Increment()` 或者 `GetCount()` 方法,它们都不会干扰到彼此的操作,因为每次只有一个线程能够持有 `_lockObject` 的锁[^1]。
---
#### 注意事项
1. **锁对象的选择**
锁定的对象应当是私有的、不可变的,并且仅限于类内部使用。这样可以避免外部代码意外地锁定或解锁同一个对象,进而引发竞争条件。
2. **避免死锁**
当程序涉及多个锁时,必须谨慎规划这些锁的获取次序,以防不同线程相互等待对方释放锁的情况发生,即所谓的“死锁”现象。
3. **性能考量**
尽管 `lock` 可有效解决多线程同步问题,但也可能带来一定的性能损耗。频繁地加锁与解锁尤其会在高并发场景下成为瓶颈。
4. **不要锁定公共类型或字符串**
使用诸如 `typeof(SomeType)` 或 `"someString"` 这样的表达式作为锁对象是非常危险的做法,因为这类对象可能是整个应用程序范围内共享的,容易引起意料之外的行为。
5. **异常处理**
即使在 `lock` 代码块内抛出了未捕获的异常,锁仍然会自动释放。不过建议开发者仍应妥善编写异常处理逻辑以应对可能出现的各种状况[^1]。
---
#### 替代方案:`Monitor` 类
实际上,`lock` 是基于 `System.Threading.Monitor` 类构建而成的一种简化形式。如果需要更加精细的控制(例如尝试获取锁但不会无限制等待),可直接利用 `Monitor` 提供的方法如 `TryEnter()` 等[^2]:
```csharp
if (Monitor.TryEnter(_lockObject, TimeSpan.FromSeconds(1)))
{
try
{
// 执行受保护的代码
}
finally
{
Monitor.Exit(_lockObject);
}
}
else
{
Console.WriteLine("未能及时取得锁");
}
```
这种方法允许设定最大等待时限,有助于减少因长时间争夺锁而导致的整体延迟。
---
### 总结
`lock` 是一个多用途且易于使用的工具,适合大多数需要保障共享资源访问独占性的场合。然而,在实际应用过程中还需留意诸多细节之处——从恰当选取锁标的物至预防潜在陷阱皆不容忽视。对于更为复杂的同步需求而言,则不妨探索其它更高级别的同步机制选项^。
阅读全文
相关推荐


















