gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 14:22:59 24 4
gpt4 key购买 nike

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

例如我有一个只有一个方法的类 (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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com