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

C#中值类型局部变量为何被多线程共享?

为什么三个线程能共享栈上的int变量?

你对值类型存储和线程栈的认知是对的,但这里的count变量因为闭包捕获的机制,实际存储位置已经发生了变化:

  • 当你在匿名委托里引用外部方法的count变量时,C#编译器会自动生成一个隐藏的类,把count作为这个类的字段(虽然int是值类型,但这个类是引用类型,实例存储在堆上)。
  • 你创建的三个线程的委托,都会持有这个隐藏类实例的引用,所以三个线程操作的是同一个堆上的count字段,自然会共享变量值,最终能累加到300(注:这段代码存在线程安全问题,极端情况下可能出现计数小于300的情况,因为++count不是原子操作)。

对比一下,如果把变量放到委托内部,每个线程就会拥有独立的局部变量:

Thread a = new Thread(delegate ()
{
    int threadCount = 0; // 每个线程自己的局部变量,存储在当前线程栈上
    for (int i = 0; i < 100; i++)
    {
        Console.WriteLine($"Thread ID : {Thread.CurrentThread.ManagedThreadId}, Count : {++threadCount}");
    }
});

你的测试代码:

public void Test()
{
    int count = 0;
    Thread a = new Thread(delegate ()
    {
        for (int i = 0; i < 100; i++)
        {
            Console.WriteLine($"Thread ID : {Thread.CurrentThread.ManagedThreadId}, Count : {++count}");
        }
    });
    a.Start();

    Thread b = new Thread(delegate ()
    {
        for (int i = 0; i < 100; i++)
        {
            Console.WriteLine($"Thread ID : {Thread.CurrentThread.ManagedThreadId}, Count : {++count}");
        }
    });
    b.Start();

    Thread c = new Thread(delegate ()
    {
        for (int i = 0; i < 100; i++)
        {
            Console.WriteLine($"Thread ID : {Thread.CurrentThread.ManagedThreadId}, Count : {++count}");
        }
    });
    c.Start();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 10:13:10