Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any reason to lock on something other than new object()?

object theLock = new object();

...


lock (theLock)
{
    ...
}

I always use a new object() for this, but I'm wondering: are there any circumstances in which you would lock on a more specific type?

like image 779
Ilya Kogan Avatar asked Mar 19 '11 09:03

Ilya Kogan


3 Answers

In my opinon any reference type can be locked, the reason why a dummy object is used is to avoid common locking pitfalls:

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.

like image 180
Captain Comic Avatar answered Oct 26 '22 23:10

Captain Comic


In case of a new, the Type doesn't matter, the instance do. In this case you're talking about a synclock object : an object which is used to lock code(s) section(s) to prevent concurrent access.

Using another Type than object for a synclock is a waste of memory because you don't use this instance for anything else.

There're circumstances in which you can lock another type : when you need to lock a specific instance. The main problem is : the instance must be initialized to lock it. And in most cases, you want to synclock the initilization of the instance :)

But in some case, you can lock the instance directly ; like a dictionary for example (well almost directly in this case ;)).

private Dictionary<string,string> _dictionary = new Dictionary<string,string>();

public void AddValue(string key, string value)
{
    lock (((IDictionary)_dictionary).SyncRoot)    // SyncRoot recommended
    {
       if (!_dictionary.ContainsValue(value))
            _dictionary.Add(key, value);
    }
}

But the point is : even if this will work, always ask yourself : "Is it not a better idea to create a specific locking object instead" ?

like image 38
JoeBilly Avatar answered Oct 26 '22 23:10

JoeBilly


I'm pretty sure you know that article Lock Statement (C# Reference).

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 since 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.

like image 32
mastak Avatar answered Oct 26 '22 23:10

mastak