Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to lock a variable used in multiple threads

I have asked a question badly over here Lock on a variable in multiple threads so for clarity I am going to ask it here and hope I can ask it correctly.

classA
  creates instance of classB
  has methodA that can update & uses classB's myVar
  has methodB that can update & uses classB's myVar

classB
  has a variable myVar

methodA and methodB can both run in separate threads (called in new threads from main). How do I ensure this is thread safe?

like image 398
SimpleOne Avatar asked Nov 02 '10 21:11

SimpleOne


People also ask

Can multiple threads take a lock simultaneously?

Only one thread can hold a lock at a time. If a thread tries to take a lock that is already held by another thread, then it must wait until the lock is released.

Can multiple threads read the same variable?

When race conditions occur. A race condition occurs when two threads access a shared variable at the same time. The first thread reads the variable, and the second thread reads the same value from the variable.

Can two threads acquire the same lock?

Typically, threads cannot acquire locks twice in a row: a thread must release an acquired lock before attempting to acquire it again. However, reentrant locks can be acquired multiple times by the same thread. Reentrant locks allow code to acquire a lock before calling other functions that acquire the same lock.

Do multiple threads share global variables?

Threads share all global variables; the memory space where global variables are stored is shared by all threads (though, as we will see, you have to be very careful about accessing a global variable from multiple threads).


3 Answers

Use the lock keyword to guard code that can be executed simultaneously by more than one thread.

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

  public void MethodA()
  {
    lock (b)
    {
      // Do anything you want with b here.
    }
  }

  public void MethodB()
  {
    lock (b)
    {
      // Do anything you want with b here.
    }
  }
}

It is important to note that lock does not guard or lock the object instance used in the statement. Instead, the object is used as a way to identify a section of code that should be prevented from executing if another section using the same object instance is already executing. In other words, you could use any object instance you like in the lock statements and it would still be safe to access members of ClassB.

like image 59
Brian Gideon Avatar answered Oct 20 '22 23:10

Brian Gideon


I've written a blog post about having multiple threads add values to a list and using lock() to prevent the writes from colliding along with why this needs to be done.

like image 40
Erik Noren Avatar answered Oct 21 '22 01:10

Erik Noren


The easiest solution: Don't share the instance of ClassB among your threads.

In other words, instantiate a new ClassB with your thread declaration and send it as a parameter.

like image 33
Austin Salonen Avatar answered Oct 20 '22 23:10

Austin Salonen