Why does the lock object have to be readonly?

后端 未结 4 1906
渐次进展
渐次进展 2020-12-29 22:29

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:



        
相关标签:
4条回答
  • 2020-12-29 22:49

    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.

    0 讨论(0)
  • 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.

    0 讨论(0)
  • 2020-12-29 23:05

    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

    private object Locker = new object();
    

    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

    Locker = new object();
    

    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.

    0 讨论(0)
  • 2020-12-29 23:11

    If I want to be sure that it will be locked for all threads inside my application:

    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.

    everyone says that the object has to be "readonly" I didn't found the reason

    Well, it doesn't have to be. This is just a best practice, which helps you to avoid errors.

    Consider this code:

    class MyClass
    {
        private object myLock = new object();
        private int state;
    
        public void Method1()
        {
            lock (myLock)
            {
                state = // ...
            }
        }
    
        public void Method2()
        {
            myLock = new object();
            lock (myLock)
            {
                state = // ...
            }
        }
    }
    

    Here Thread1 can acquire lock via Method1, but Thread2, which is going to execute Method2, will ignore this lock, because lock object was changed => the state can be corrupted.

    0 讨论(0)
提交回复
热议问题