Lock on a variable in multiple threads

☆樱花仙子☆ 提交于 2019-12-09 16:55:25

问题


I am very new to C# and I wanted to ask if I have this situation in MULTI THREADS (pseudo code):

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;
     }
}

If someMethod() and MethodA() can be active in separate threads, then MethodA() could evaluate the if statement as true; but before it sets myVar = 0, someMethod() sets myVar = 0 making it incorrect to have set myVar to 0 in MethodA()!!

Basically, how do I lock myVar:

  • can I lock{} on myVar's property (set, get)
  • do I need to use Interlock (I have no experience yet of Interlock though)?

回答1:


You should create a private object that will allow for locking:

private readonly object _locker = new object();

Then in your property get/set methods, lock around it:

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

Make sure your method uses the lock also:

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



回答2:


It looks like you are trying to implement some sort of signalling mechanism. Instead of writing your own you could use one of the classes provided in the .NET library such as ManualResetEvent.




回答3:


This is how I do it.

    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; } }
    }



回答4:


I would certainly rethink your overall approach, but if you are wanting to synchronize access to the members of ClassB from different sections of code then you could steal a not-so-good design pattern from the ICollection interface and expose a SyncRoot property that can be used to acquire the same lock as the original instance.

public class ClassA
{
  private ClassB c = new ClassB();

  public void someMethod()
  {
    lock (c.SyncRoot)
    {
      c.MyVar = 1;
      // Some other stuff
      c.MyVar = 0;
    }
  }
}

public class ClassB
{
  private object m_LockObject = new object();
  private int m_MyVar;

  public object SyncRoot
  {
    get { return m_LockObject; }
  }

  public int MyVar
  {
    get { lock (SyncRoot) return m_MyVar; }
    set { lock (SyncRoot) m_MyVar = value; }
  }

  public void MethodA()
  {
    lock (SyncRoot)
    {
      if (m_MyVar == 1) m_Var = 0;
    }
  }
}



回答5:


Is there a reason you have multiple threads sharing the same instance of your class instead of implementing each thread so that it gets its own instance of your class within its scope?



来源:https://stackoverflow.com/questions/4081986/lock-on-a-variable-in-multiple-threads

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!