c# - 多线程共享局部变量

标签 c# multithreading local shared

我试图完全理解创建调用类实例的相同方法的单独线程如何影响方法中的局部变量。

例如我有一个只有一个方法的类 (Divide)

public class Maths
{
    public int Num1;
    public int Num2;

    public void Divide()
    {
        for (long i = 0; i < 100000; i++)
        {
            Num1 = 2;
            Num2 = 2;
            int result = Num1 / Num2;
            Num1 = 0;
            Num2 = 0;
        }
    }
}

实例化两个线程,调用divide方法如下:

    static void Main(string[] args)
    {
        Maths m = new Maths();

        Task t1 = new Task(() => m.Divide());
        Task t2 = new Task(() => m.Divide());

        List<Task> tl = new List<Task> { t1, t2 };
        Parallel.ForEach(tl, task => task.Start());

        Console.ReadLine();
    }

}

有时这段代码运行正常。但有时它会在该行抛出一个除零错误:

整数结果 = Num1/Num2;

我的假设是其中一个线程在另一个线程调用 Num1/Num2 之前将 Num1 和 Num2 重置为零。因此导致被零除异常。

这是有道理的,我应该使用锁,但我不明白这些局部变量 Num1 和 Num2 如何在线程之间共享,因为我的理解是局部变量不在线程之间共享?

最佳答案

你是对的,局部变量不在线程之间共享(通常,每次调用方法时,都会在执行线程的堆栈上分配新的局部变量集,因此每个方法调用的局部变量是完全独立和修改的其中一个对其他没有影响)。

但不幸的是Num1Num2 不是局部变量,而是fields .同一类实例的字段在线程之间共享。

您需要像这样声明它们以使它们成为局部变量:

public class Maths
{
    public void Divide()
    {
        int Num1;
        int Num2;

        for (long i = 0; i < 100000; i++)
        {
            Num1 = 2;
            Num2 = 2;
            int result = Num1 / Num2;
            Num1 = 0;
            Num2 = 0;
        }
    }
}

或者,您可以为每个线程创建单独的 Maths 类实例,因此每个线程将使用不同实例的字段 Num1Num2 数学课:

static void Main(string[] args)
{
    Maths m1 = new Maths();
    Maths m2 = new Maths();

    Task t1 = new Task(() => m1.Divide());
    Task t2 = new Task(() => m2.Divide());

    List<Task> tl = new List<Task> { t1, t2 };
    Parallel.ForEach(tl, task => task.Start());

    Console.ReadLine();
}

关于c# - 多线程共享局部变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47366344/

相关文章:

php - 我可以在不需要 http Web 服务器的情况下进行 php 调用吗(在本地客户端应用程序中)

jquery - 检索以某些单词开头的 localStorage 值

docker - 如何在不复制的情况下使用本地输入文件在容器中运行命令

c# - 使用for循环将多条记录插入SQL Server数据库

C# 正则表达式验证程序验证

WPF:如何将数据从另一个域编码到用户控件

Web 应用程序中的 C# 线程问题

c# - 访问客户端添加的列表框项目

c# - 倒计时器中的重置按钮

Java 多线程适用于 Windows 但不适用于 Ubuntu