调用相同对象的多个线程同时起作用.它会引起问题吗?

Ami*_*rge 6 c# multithreading

假设我有以下C#类

class MyClass
{
    private int _i;
    private object _locker = new object();

    public void DoSomething()
    {
        var b = 2;

        // some work that depends on b being 2

        lock(_locker)
        {
            _i = 3;
        }

        // some more work

        b = -1;

        // some more work
    }
}
Run Code Online (Sandbox Code Playgroud)

我用这种方式,

//Usage:

var myobject = new MyClass();
new Thread(new ThreadStart(() => myobject.DoSomething())).Start();
new Thread(new ThreadStart(() => myobject.DoSomething())).Start();
Run Code Online (Sandbox Code Playgroud)

以下序列可以发生吗?

Thread 1 is halfway through its work.
Thread 2 just starts. Sets b = 2. 
Thread 1 sets b = -1. 
Thread 2 is confused because it expected b to be 2 but its -1.
Run Code Online (Sandbox Code Playgroud)

重要的是,这b是一个局部变量.两个线程是否可以访问b的同一个实例?我理解,对于实例变量_i,这将发生.因此,lock构造.但我不确定是否需要锁定局部变量.

Bro*_*ass 11

当调用者输入方法时,局部变量将被置于堆栈中DoSomething().每个线程在一个单独的堆栈上运行,并将获得自己唯一的局部变量.

维基百科中用于线程本地存储的这部分也适用于C#线程:

换句话说,当来自同一进程的线程引用时,静态或全局变量中的数据通常总是位于相同的存储器位置.然而,堆栈上的变量是线程本地的,因为每个线程都有自己的堆栈,驻留在不同的内存位置.

  • @Amith:如果在方法中创建对象,*对象引用*仍然存储在堆栈中,而对象本身将在堆上分配.从根本上说,这不会改变任何东西,因为每个线程都有自己的对象引用到堆上的不同对象. (3认同)
  • 我知道在我的例子中,`b`是一种原始类型.但是假设`b`是某个类的对象.我正在修改它的财产.现在`b`是一个引用类型,它仍然会在每个线程的本地堆栈上吗?我认为引用类型对象存储在所有线程共享的堆内存中... (2认同)