简体   繁体   中英

Lock on a variable in multiple threads

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)?

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

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 .

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

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM