线程之间是否共享一个方法的局部变量?

Mil*_*jad 2 c# multithreading synchronization

我有一个像这样的类的实例:

public class One
{
    Semaphore S = null;
    public One(Semaphore S)
    {
        this.S = S;
    }
    public void Run(int ID)
    {
        S.WaitOne();
        Console.WriteLine("Thread [" + ID + "] Entered");
        Random R = new Random();
        Thread.Sleep(R.Next(100, 1000));
        Console.WriteLine("Thread [" + ID + "] Exited");
        S.Release();
    }
}
Run Code Online (Sandbox Code Playgroud)

在我的程序中,我实例化了几个新线程.每个线程在上面的类中运行"Run()"方法.

Semaphore S = new Semaphore(5, 5);
One O = new One(S);
for (int j = 0; j < 10; j++)
{
     Thread T = new Thread(delegate() { O.Run(j); });
     T.Start();
}
Run Code Online (Sandbox Code Playgroud)

我希望看到一个从0到9的数字列表,但是按照非排序顺序.但是我的结果显示"Run()"方法中的"ID"变量作为局部变量在所有线程之间共享.

 ![Output][1]
Run Code Online (Sandbox Code Playgroud)

我想知道我是否有一个类的实例,并且许多线程从该实例运行一个方法,那么该方法的局部变量是否在所有线程之间共享?或者每个线程都有自己的本地副本?我应该为该类中的每个线程创建一个新实例吗?

Hen*_*man 6

不,线程之间不共享局部变量.而你的参数ID在这方面是一个局部变量.它不是共享的.

您所看到的是由称为捕获的循环变量的标准问题引起的.使用额外变量解决它很简单:

for (int j = 0; j < 10; j++)
{
     int copy = j;
     Thread T = new Thread(delegate() { O.Run(copy); });
     T.Start();
}
Run Code Online (Sandbox Code Playgroud)

我希望这显示出问题所在:j变量由匿名方法捕获,实际上这意味着它由所有调用站点共享(通过引用)O.Run().