锁定多个线程中的变量

时间:2010-11-02 20:51:15

标签: c# multithreading variables locking

我是C#的新手,我想询问我是否在MULTI THREADS(伪代码)中遇到这种情况:

public class ClassA
{
     ClassB c = new ClassB();
     public void someMethod()
     {
          c.myVar = 1;
          // Some other stuff
          c.myVar = 0;
     }
}

public class ClassB
{
     internal int myVar;

     public void MethodA()
     {
        if(myVar = 1)
              myVar = 0;
     }
}

如果someMethod()MethodA()可以在不同的线程中处于活动状态,那么MethodA()可以将if语句评估为true;但在设置myVar = 0之前,someMethod()设置myVar = 0使得myVar中将MethodA()设置为0不正确!!

基本上,如何锁定myVar

  • 可以在lock{}的{​​{1}}属性(设置,获取)
  • myVar
  • 我是否需要使用Interlock(我还没有Interlock的经验)?

5 个答案:

答案 0 :(得分:16)

您应该创建一个允许锁定的私有对象:

private readonly object _locker = new object();

然后在你的属性get / set方法中,锁定它:

get { lock (_locker) { return this.myVar; } }
set { lock (_locker) { this.myVar = value; } }

确保您的方法也使用锁:

public void MethodA()
{
    lock(_locker)
    {
        if(myVar == 1)
          myVar = 0;
    }
}

答案 1 :(得分:3)

看起来您正在尝试实现某种信令机制。您可以使用.NET库中提供的类之一,而不是编写自己的类,例如ManualResetEvent

答案 2 :(得分:1)

我就是这样做的。

    static readonly object _myVar_Lock = new object();
    private int _myVar = 0;

    public int myVar
    {
        get { lock (_myVar_Lock) { return this._myVar; } }
        set { lock (_myVar_Lock) { this._myVar = value; } }
    }

答案 3 :(得分:1)

我肯定会重新考虑您的整体方法,但如果您想要从代码的不同部分同步对ClassB成员的访问权限,那么您可以从{{1}中窃取一个不那么好的设计模式接口并公开一个ICollection属性,该属性可用于获取与原始实例相同的锁。

SyncRoot

答案 4 :(得分:-1)

有没有理由让多个线程共享同一个类的实例而不是实现每个线程,以便它在其范围内获得自己的类实例?