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

Interlocked类:读先写竞态条件问题及无阻塞解决方案咨询

非阻塞式解决竞态条件问题

你说的没错,问题就出在检查条件和执行Increment的间隙。多个线程可能同时通过Interlocked.CompareExchange读到同一个小于500000的值,然后各自执行Interlocked.Increment,最后就会多出来一次递增,导致结果变成500001。

非阻塞的核心思路是把「检查+更新」做成原子操作,这里可以用循环结合Interlocked.CompareExchange来实现:

using System;
using System.Threading;
using System.Threading.Tasks;

namespace InterlockedLearning
{
    class Program
    {
        static int sharedVariable = 0;

        static void Main()
        {
            Parallel.For(0, 1000000, Func1);
            Console.WriteLine("Thread{0} sharedVariable: {1}", Thread.CurrentThread.ManagedThreadId, sharedVariable);
            Console.Read();
        }

        public static void Func1(int val)
        {
            int currentValue;
            do
            {
                currentValue = Interlocked.CompareExchange(ref sharedVariable, 0, 0);
                // 如果当前值已经不满足条件,直接退出循环
                if (currentValue >= 500000)
                    break;
                // 尝试把currentValue更新为currentValue+1,只有当当前值还是currentValue时才成功
            } while (Interlocked.CompareExchange(ref sharedVariable, currentValue + 1, currentValue) != currentValue);
        }
    }
}

方案说明:

  • 每次循环先读取当前的sharedVariable值
  • 如果值已经≥500000,直接退出,不再尝试递增
  • 否则,尝试用CompareExchange把值从currentValue改成currentValue+1:如果这期间没有其他线程修改过值,CAS操作成功,循环结束;如果被其他线程修改了,CAS失败,就重新进入循环读取新值再尝试

这样整个「检查是否可以递增+执行递增」的逻辑就变成了原子性的操作,不会出现多个线程同时通过检查然后重复递增的情况,最终结果会稳定在500000。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 18:03:22