You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#/.NET如何使用threading的Monitor实现无独占锁的特殊线程同步需求

你的需求可以实现,完全兼容当前Monitor的使用习惯,实现逻辑如下:

实现方案

你现有的线程1独占锁逻辑不需要做任何修改,仅需调整线程2的执行逻辑即可:

  • 线程2优先调用Monitor.TryEnter(lockObj, 0)无等待尝试获取锁,若获取成功说明当前无其他线程持有独占锁,直接释放锁后即可运行业务逻辑,符合你「无需获取独占锁即可运行」的要求
  • 若Monitor.TryEnter返回失败,说明当前有其他线程持有独占锁,此时调用阻塞式的Monitor.Enter等待锁释放,拿到锁后立即释放,即可开始运行业务逻辑

代码示例

// 公共锁对象,和线程1使用的是同一个实例
private static readonly object lockObj = new object();

// 线程1原有逻辑无需修改
void Thread1Logic()
{
    bool lockTaken = false;
    try
    {
        Monitor.Enter(lockObj, ref lockTaken);
        // 线程1的独占业务逻辑
    }
    finally
    {
        if (lockTaken)
        {
            Monitor.Exit(lockObj);
        }
    }
}

// 线程2适配逻辑
void Thread2Logic()
{
    bool lockTaken = false;
    try
    {
        // 无等待尝试拿锁,判断当前是否存在独占锁
        Monitor.TryEnter(lockObj, 0, ref lockTaken);
        if (!lockTaken)
        {
            // 存在其他线程的独占锁,阻塞等待锁释放
            Monitor.Enter(lockObj, ref lockTaken);
        }
        // 立即释放锁,无需持有锁运行业务
    }
    finally
    {
        if (lockTaken)
        {
            Monitor.Exit(lockObj);
        }
    }

    // 此处运行线程2的业务逻辑
}

注意事项

  • 上述实现存在极短的时间窗口:锁释放到线程2业务逻辑执行的间隙,可能有其他线程再次获取到独占锁。如果你的业务场景不允许该间隙存在,仅需要把线程2的业务逻辑移到try代码块内部、锁持有期间运行即可,线程2仅会持有锁极短时间,对原有线程1的逻辑影响可忽略不计。
  • 所有Monitor加锁操作必须配合finally块释放锁,避免出现异常时锁无法释放导致死锁。

内容的提问来源于stack exchange,提问作者Thomas Carlton

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 16:15:00