我正在尝试用C#学习线程,我看到一些文章中出现了一些内容,但我不确定我是否完全理解它: 在给出的两个例子中,锁定'this'和'thisLock'之间的根本区别是什么。
示例1:
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;
}
}
}
示例2:
class Account
{
decimal balance;
public void Withdraw(decimal amount)
{
lock (this)
{
if (amount > balance)
{
throw new Exception("Insufficient funds");
}
balance -= amount;
}
}
}
根据我的理解,我会认为'thisLock'只会阻止其他线程进入特定的代码区域。
如果锁定'this'会停止对象的所有操作,即其他线程调用其他方法?
我是否从根本上错过了解这一点,或者这是正确的结论?
答案 0 :(得分:2)
两种情况都会产生完全相同的效果。一个区别是其他对象看不到thisLock
,因此您可以确定没有其他对象可以重用锁。如果你锁定this
,另一部分代码也可以锁定同一个帐户实例。
答案 1 :(得分:1)
区别在于锁定粒度。
当锁定对象时,(简化)在实例上设置了一个位。尝试锁定同一实例的任何其他人都将处于等待状态,直到锁定被另一个释放为止。
在许多情况下,可以同时使用对象上的方法(i.o.w.并行)。如果该方法也使用“lock(this)
”,则锁定整个对象(this)将排除使用任何其他方法。
由于可以在任何引用类型上使用锁,我们可以创建“锁定”对象。我们在排除的基础上实施“lock(lockObject)
”。
例如;
MethodB1和MethodB2不能同时使用
MethodA1 / 2可与MethodB1 / 2同时使用。
如果我们在每个方法上都使用lock(this)
,我们也会将MethodA1 / 2排除在与MethodB1 / 2同时运行的时候。
通过创建2个锁定对象(lockAMethods,lockBMethods),我们现在可以更精细地实现锁定。
lock(lockAMethods)
”来确保A1和A2方法不能同时运行。"lock(lockBMethods)
“确保B1和B2方法无法同时运行。我们可以同时lock(lockAMethods)
和lock(lockBMethods)
。因此,我们现在可以在MethodB1 / 2的同时运行MethodA1 / 2。
希望这有帮助,
答案 2 :(得分:0)
你说
根据我的理解,我会认为'thisLock'只会停止 其他线程进入特定的代码区域。
如果锁定'this'会停止对象的所有操作,即其他线程调用其他方法?
无论您在两个语句中使用lock(this)
还是lock(thisLock)
,它都只会阻止其他线程进入该特定代码区域。
但作为一般惯例,始终建议不要使用 lock(this)
而是创建另一个对象并在该对象上放置lock
。
编辑是的,因为Sriram Sakthivel
已发表评论,他是绝对正确的,请阅读Why is lock(this) {...} bad?了解更多有关我们应该避免的问题lock(this)