C# 为什么需要冗余锁对象?
出于好奇,我正在查看MSDN上的C# 为什么需要冗余锁对象?,c#,multithreading,locking,C#,Multithreading,Locking,出于好奇,我正在查看MSDN上的lock关键字: class Account { decimal balance; private Object thisLock = new Object(); public void Withdraw(decimal amount) { lock (thisLock) { if (amount > balance) {
lock
关键字:
class Account
{
decimal balance;
private Object thisLock = new Object();
public void Withdraw(decimal amount)
{
lock (thisLock)
{
if (amount > balance)
{
throw new Exception("Insufficient funds");
}
balance -= amount;
}
}
}
在上面的示例中,对象
thisLock
与lock
关键字一起使用。为什么需要这样做?它似乎没有任何其他用途。为什么不让lock
关键字单独存在呢?lock
关键字本身不能存在,它总是使用一个参数作为信号量(同步对象),只允许一个线程继续
只有一个线程可以锁定同步对象(在本例中,
每次锁定一次,所有争用线程都会被阻塞,直到释放锁为止。如果有多个线程争用锁,则它们是
在“就绪队列”上排队,并在先到时授予锁,
先到先得(警告是
Windows和CLR意味着队列的公平性有时会受到影响
(被侵犯)
这里有几个方面:
语句需要一个对象引用作为标识符。它必须有一些东西来标识这个锁,并将它与代码中可能存在的任何其他锁分开lock
- 您要保护的数据不是引用类型,因此需要使用其他内容作为锁的标识符
- 建议使用仅用作锁标识符的私有对象,即使可以将数据本身用作标识符。这样,就没有理由在类外公开引用,因为如果引用在类外的锁中使用,则可能会出现死锁
如果没有对象,就不可能有不同的令牌,所有同步都将依赖于单个内部令牌。这将不会非常有效 lock关键字本身将是无效的C#。你在考虑
lock(this){…}
?我认为理论上,C语言/编译器可以允许类似lock()
的语法,这将为特定的锁处理一个唯一的对象。但是会引起一些可用性问题,例如:锁是静态的还是实例级的?更不用说,在意外放置lock()
而不是lock(mySharedSyncObject)
的地方,可以非常轻松地意外不共享锁。完全避免它更容易,只需让我们承担应用锁定意图的责任即可。@ChrisSinclair您的回答给出了我想要的。谢谢。把lock
想象成锁门。哪个门被锁上了?这是一个相关的问题,不是吗?是的,这显然是某种单一的参考点,但我只是感到困惑,为什么语言中的功能需要开发人员为作业实例化一个对象,而它可以是自动/内置的?所以我在想也许还有更多。@MuhammadA假设一个类中任何一个lock
语句都会使用同一个对象来锁定。这是一个错误的假设。虽然这可能是最常见的操作,但锁定不同的对象(动态确定或静态确定)也是很常见的。这就是lock
非常灵活的原因。例如,查看of,它为表的每个部分使用单独的lock对象。这允许同时访问字典(即使在删除和添加对象时),只要这些访问发生在表的不同部分。共享一个锁定对象意味着一次只能执行一个操作。