[英]Why does the lock object have to be readonly?
在实现锁时,我曾经在我的类中创建一个私有对象:
如果我想确保它被锁定在创建我的类的线程中:
private object Locker = new object();
如果我想确保它将为我的应用程序中的所有线程锁定:
private static object Locker = new object();
但是在这里: 为什么锁对象必须是静态的?
在其他一些问题中,每个人都说对象必须是readonly
。 我还没有找到原因——甚至在 MSDN 或 JavaDoc 中也没有。
由于我经常使用这种结构,有人可以向我解释为什么我应该使用readonly
吗?
谢谢!
如果我想确保它将为我的应用程序中的所有线程锁定:
如果锁定对静态状态的访问,则锁定对象必须是静态的。
否则它必须是实例,因为不需要锁定一个类实例的状态,并防止其他线程同时与另一个类实例一起工作。
每个人都说对象必须是“只读的”我没有找到原因
好吧,它不一定是。 这只是一个最佳实践,它可以帮助您避免错误。
考虑这段代码:
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 = // ...
}
}
}
这里 Thread1 可以通过Method1
获取锁,但是将要执行Method2
的 Thread2 将忽略此锁,因为锁对象已更改 => 状态可能已损坏。
它不必是只读的,但这是一个很好的做法,因为它可以避免您意外更换它,这可能会导致一些难以追踪的错误。
我猜这意味着“引用锁定对象的变量应该是只读的”。
您锁定变量引用的锁定对象,而不是变量本身。 即有
private object Locker = new object();
你锁定那个新对象(),而不是 Locker 字段。 然后,如果您将字段的值替换为对另一个对象的引用,例如
Locker = new object();
并锁定它,您将锁定两个不同的对象,这违背了锁定的目的,因为您现在没有获得同步访问。
理想情况下,该对象应该是只读的,这样就不能将其更改为指向另一个对象。 如果您对一个对象进行了锁定,然后另一个线程更改了该对象,如果,然后另一个线程出现并尝试对该对象进行锁定,则所讨论的对象将不同,因此原始锁定将是无效。
这将是非常罕见的情况。 但是,如果您在对象上有一个锁,并且另一个线程在该对象上等待,如果锁定线程调用 Monitor.Pulse,则等待线程被唤醒,并且可以获取该对象上的锁。 在被唤醒和获取锁之间的那段时间里,另一个线程可以更改锁中引用的对象,因此等待线程将获取另一个对象的锁。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.