简体   繁体   English

为什么锁对象必须是只读的?

[英]Why does the lock object have to be readonly?

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 .在其他一些问题中,每个人都说对象必须是readonly I haven't found the reason - not even in MSDN or JavaDoc.我还没有找到原因——甚至在 MSDN 或 JavaDoc 中也没有。

As I use this kind of construction quite often, could someone explain to me why should I use readonly ?由于我经常使用这种结构,有人可以向我解释为什么我应该使用readonly吗?

Thanks!谢谢!

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.这里 Thread1 可以通过Method1获取锁,但是将要执行Method2的 Thread2 将忽略此锁,因为锁对象已更改 => 状态可能已损坏。

它不必是只读的,但这是一个很好的做法,因为它可以避免您意外更换它,这可能会导致一些难以追踪的错误。

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.您锁定变量引用的锁定对象,而不是变量本身。 Ie having即有

private object Locker = new object();

you lock on that new object(), not on Locker field.你锁定那个新对象(),而不是 Locker 字段。 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.并锁定它,您将锁定两个不同的对象,这违背了锁定的目的,因为您现在没有获得同步访问。

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.但是,如果您在对象上有一个锁,并且另一个线程在该对象上等待,如果锁定线程调用 Monitor.Pulse,则等待线程被唤醒,并且可以获取该对象上的锁。 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.在被唤醒和获取锁之间的那段时间里,另一个线程可以更改锁中引用的对象,因此等待线程将获取另一个对象的锁。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM