When implementing a lock, I used to create a private object inside of my class:
If I want to be sure that it is locked in the thread that created my class:
private object Locker = new object();
If I want to be sure that it will be locked for all threads inside my application:
private static object Locker = new object();
But here: Why does the lock object have to be static?
and in a number of other questions, everyone says that the object has to be readonly
. I haven't found the reason - not even in MSDN or JavaDoc.
As I use this kind of construction quite often, could someone explain to me why should I use readonly
?
Thanks!
I guess what meant is "a variable referencing a lock object should be read only".
You lock on a lock object that variable references, not on a variable itself. I.e. having
you lock on that new object(), not on Locker field. Then, if you replace the value of the field with a reference to another object, say
and lock on it, you are locking on two different objects, and that defeats the purpose of the locking, because you do not get a synchronized access now.
The object should ideally be readonly so that it cannot be changed to point to another object. If you took a lock on an object, then another thread changes the object, if, then another thread comes along, and tries to take a lock on this object, the object in question would not be the same, so the original lock would be invalidated.
This would be a very rare case. But if you had a lock on the object, and another thread waiting on that object, if the locking thread calls Monitor.Pulse, the waiting thread is awoken, and can take the lock on the object. In that period of time between being woken and taking the lock, another thread could change the object that is referenced in the lock, and so the waiting thread would take a lock on a different object.
It doesn't have to be readonly, but it's good practise to as it saves you from accidentally replacing it, which can lead to some difficult to track down bugs.
The lock object has to be static, if it locks access to static state.
Otherwise it has to be instance, because there's no need to lock state of one class instance, and prevent other threads to work with another class instance at the same time.
Well, it doesn't have to be. This is just a best practice, which helps you to avoid errors.
Consider this code:
Here Thread1 can acquire lock via
Method1
, but Thread2, which is going to executeMethod2
, will ignore this lock, because lock object was changed => the state can be corrupted.