Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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(this) {…} bad?

like image 359
senzacionale Avatar asked Jul 31 '11 19:07

senzacionale


People also ask

Does a lock variable have to be static?

It doesn't have to be static, in fact sometimes it should not be static. The variable should live in the same scope as the methods where you use it for locking. If the methods are static, the variable should be static, and if the methods are instance methods, the variable should be an instance varible.

What is the use of class object lock in Java?

This lock is used when we want a non-static method or non-static block of our code should be accessed by only one thread at a time. This lock is used to make static data thread-safe. This lock is used to make non-static data thread-safe. Multiple objects of a particular class may exist but there is always one class’s class object lock available.

Can I lock all methods in an instance of a method?

If the methods are static, the variable should be static, and if the methods are instance methods, the variable should be an instance varible. A static variable will still work when used to lock in an instance method, but then you will be locking too much. You will lock all methods in all instances, not just the methods in the same instance.

What is democlass level lock in Java?

Class level lock prevents multiple threads to enter in synchronized block in any of all available instances of the class on runtime. This means if in runtime there are 100 instances of DemoClass, then only one thread will be able to execute demoMethod () in any one of instance at a time, and all other instances will be locked for other threads.


2 Answers

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.

like image 193
Steven Avatar answered Oct 29 '22 09:10

Steven


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.

like image 39
Ben Avatar answered Oct 29 '22 09:10

Ben