Difference between lock(this) and a lock on static object
Which of the following two code snippets is better to use?
static readonly object _locker = new object();
lock (_locker)
or
lock (this)
this
is an object of the current instance. So why is lock (_locker)
always in the books?
Related:
What is the difference between lock(this) and lock(thisLock)? Why is lock(thi开发者_StackOverflow中文版s) {…} bad?
There could be a big difference. The biggest difference between the two is that the first example uses a single object to lock on (hence the static
keyword) while the this
keyword in the second example implies locking on an instance. There could therefore be a big difference from a performance perspective and even from a correctness perspective, but that depends on the code inside the lock.
When all you need is to synchronize access to instance level fields, you should not use the static
keyword, since that will synchronize the code itself, instead of the data (which could cause an unneeded performance hit). Of course, if the data itself is static (class level data instead of instance level data), you need to use the static
keyword. On the other hand, when you use the this
keyword to lock, while you're accessing shared / static resources, you will (of course) have a correctness problem, since synchronization is on an instance basis and multiple instance will still be able to access the shared data at the same time.
And there is another problem, but the difference is much smaller than for the previously noted differences. The first example uses a privately declared object to lock on, while the other uses the this
pointer, which is the reference to the object of that instance method itself. Because this reference is publicly accessible to other objects, it is possible for them to lock on it, which could cause deadlocks in rare circumstances. If you're an application developer, I wouldn't worry to much about this (as long as you don't lock on things like System.String
or System.Type
), but if you are a framework developer, you should certainly not use lock(this)
, since there is no way to tell in what way application developers will (ab)use your code.
It's almost always preferable to lock on a private readonly object.
The difference is that this
is generally visible to outside code, which may take a lock on it, i.e. -
var obj = new YourClass();
lock(obj)
{
...
}
...in which case any attempt inside of YourClass
to lock (this)
would block.
Because you don't want the lock to be accessed from outside the object.
If you use lock(this) you can get a deadlock:
void blah() {
lock(this);
sleep(200);
}
//Some other block of code
MyObject a;
foreach(Mythread m in threads)
{
lock(a);
m.Call(a.blah); //Not the best syntax, but you get the idea.
}
If you keep the lock inside the object it wouldn't deadlock.
精彩评论