System.Threading.Lock与lock语句的比较与差异

传统 lock 语句的用法

传统 lock 语句是 C# 中最常用的同步机制,用于确保代码块在多个线程中互斥执行。其语法简洁,直接作用于对象引用。

private readonly object _lockObj = new object();

public void ThreadSafeMethod()
{
    lock (_lockObj)
    {
        // 临界区代码
    }
}
System.Threading.Lock 的用法

System.Threading.Lock 是 .NET 中更底层的同步原语,提供更细粒度的控制。它需要显式调用 EnterExit 方法。

private readonly object _lockObj = new object();

public void ThreadSafeMethod()
{
    bool lockTaken = false;
    try
    {
        System.Threading.Monitor.Enter(_lockObj, ref lockTaken);
        // 临界区代码
    }
    finally
    {
        if (lockTaken)
            System.Threading.Monitor.Exit(_lockObj);
    }
}
主要差异
  1. 语法复杂度
    lock 语句语法更简洁,自动处理 Monitor.EnterMonitor.Exit
    System.Threading.Monitor 需要手动管理锁的获取和释放。

  2. 异常处理
    lock 语句在异常时自动释放锁。
    System.Threading.Monitor 需在 finally 块中显式释放锁,否则可能导致死锁。

  3. 超时控制
    lock 语句不支持超时机制。
    System.Threading.Monitor.TryEnter 可设置超时时间,避免无限等待。

bool lockTaken = false;
try
{
    System.Threading.Monitor.TryEnter(_lockObj, 1000, ref lockTaken);
    if (lockTaken)
    {
        // 临界区代码
    }
    else
    {
        // 超时处理
    }
}
finally
{
    if (lockTaken)
        System.Threading.Monitor.Exit(_lockObj);
}
  1. 性能影响
    lock 语句编译后实际转换为 System.Threading.Monitor 调用,性能差异可忽略。
    直接使用 Monitor 可优化特定场景(如超时控制)。
适用场景
  • 优先使用 lock 语句
    简单同步需求,代码可读性更重要时。

  • 使用 System.Threading.Monitor
    需要超时控制、更灵活的锁管理或与其他同步机制(如 Wait/Pulse)配合时。

注意事项
  • 避免锁定 public 对象或字符串,可能引发外部代码的意外死锁。
  • 确保锁范围尽可能小,减少线程阻塞时间。

更多推荐