Best Practices in using a lock

I normally use a private member variable not a property, ie

private static object MyLock = new object();

This way its always initialised.

You can also use a non static version such as

private readonly object MyLock = new object();

From documentation: https://msdn.microsoft.com/en-us/library/c5kehkcz.aspx

In general, avoid locking on a public type, or instances beyond your code's control. The common constructs lock (this), lock (typeof (MyType)), and lock ("myLock") violate this guideline:

  • lock (this) is a problem if the instance can be accessed publicly.
  • lock (typeof (MyType)) is a problem if MyType is publicly accessible.
  • lock("myLock") is a problem because any other code in the process using the same string, will share the same lock.

Best practice is to define a private object to lock on, or a private static object variable to protect data common to all instances.

Sample:

 class Account
{
    decimal balance;
    private Object thisLock = new Object();

    public void Withdraw(decimal amount)
    {
        lock (thisLock)
        {
            if (amount > balance)
            {
                throw new Exception("Insufficient funds");
            }
            balance -= amount;
        }
    }
}

Synchronizing on

SyncRoot ?? new object()

makes no sense, because if SyncRoot is null, each thread will get a new object every time. Synchronizing on separate objects has no effect: threads will continue right away, because nobody else could possibly synchronize on the same new object.

You should initialize SyncRoot in the constructor, before the first thread tries to obtain a lock.


The first will be a problem, as it will not lead to any good synchronization:

lock (SyncRoot ?? new object())
    SomeMethod();

The reason being is that if you create a new object and not assign it to SyncRoot it will be placed on the heap, but there will be no reference to it. So when another thread comes, it will not find it... It becomes absolutely useless and it won't block any access to the critical section.

The second approach will work, though I really cannot understand why you would like to use the lock if it is available only.

Tags:

C#

Locking