sel*_*ams 3 c# multithreading shared local
我试图完全理解如何创建调用类实例的相同方法的单独线程可以影响方法中的局部变量.
例如,我有一个单一方法的类(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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
实例化两个线程,并且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();
}
}
Run Code Online (Sandbox Code Playgroud)
有时这段代码运行正常.但有时候它会抛出一个divbyzero错误:
int result = Num1/Num2;
我的假设是其中一个线程在另一个线程调用Num1/Num2之前将Num1和Num2重置为零.因此导致除零异常.
这是有道理的,我应该使用锁,但我不明白这些局部变量Num1和Num2如何在线程之间共享,因为我的理解是局部变量不在线程之间共享?
你是正确的,局部变量不是在线程之间共享的(通常,每次调用方法时,它的新局部变量都在执行线程的堆栈上分配,因此每个方法调用的局部变量是完全独立的,并且修改其中一个它们对其他人没有影响).
但可惜的是Num1并Num2没有局部变量,但场.类的同一实例的字段在线程之间共享.
您需要像这样对它们进行declate以使它们成为局部变量:
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
或者,您可以Maths为每个线程创建单独的类实例,因此每个线程将使用字段Num1和类Num2的不同实例Maths:
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();
}
Run Code Online (Sandbox Code Playgroud)