I'm reading lock Statement (C# Reference) where I saw this code:
class Account
{
private Object thisLock = new Object();
//...
int Withdraw(int amount)
{
lock (thisLock)
{
//....
}
}
//...
}
I'm wondering if it would make any difference if we write lock(this)
instead of lock(thisLock)
in the above example. Please see the complete example if your answer depends on it.
If you think there is indeed some difference be开发者_开发知识库tween lock(this)
and lock(thisLock)
, then please help me understanding the difference with all important points. In particular, what does each exactly mean?
The difference stems from the fact that lock
, if misused, can result in thread deadlock. If the lock target's visibility is unknown to you (i.e., you cannot be 100% certain who has a reference to the target and if/when they might lock
it), then you cannot really know if the application might experience a deadlock.
For this reason it's customary to lock on a private
member: since it's private and it's in your code, you do know that noone else can lock
it.
Of course all this is a purely academic difference most of the time (usually people don't go around locking random objects), but it's a good defensive coding practice.
The page you link to states:
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.
Because someone else might lock the instance using a reference they have, and your code that does lock(this)
will of course not expect that. Example on IDEone (see line 26).
lock (typeof (MyType)) is a problem if MyType is publicly accessible.
A variation of the above, if the type is visible to other code then you might end up trying to lock the same instance as that code (typeof
returns singleton instances).
lock("myLock") is a problem because any other code in the process using the same string, will share the same lock.
Another variation: due to string interning, code ends up trying to lock the same instance.
Best practice is to define a private object to lock on, or a private static object variable to protect data common to all instances.
When you do lock(this)
you don't have full control of this
because you don't know who else would be using this
or instance of your class. It is safe to use a local object because that local object would be available only inside your class hence you will have full control on it
see this for details
精彩评论