使用对象而不是 this 来获取锁 - 线程化
使用对象而不是 this 来获取锁 - 线程化
这个问题已经有答案了:
我正在学习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”加锁将停止对象上的所有操作,例如其他线程对其他方法的调用?
我是否从根本上误解了这一点,或者这是正确的结论?
admin 更改状态以发布 2023年5月23日
区别在于锁定的粒度。
当锁定一个对象时(简化),实例上会设置一个位。任何试图锁定同一实例的其他人都会陷入等待状态,直到由其他人释放锁定。
在许多情况下,对象上的方法可以同时使用(即并行)。如果该方法还使用 'lock(this)
',则锁定整个对象(this)将排除任何其他方法的使用。
由于锁可以用于任何引用类型,我们可以创建“锁定”对象。 我们在排除基础上实现了 'lock(lockObject)
'。
例如;
- MethodA1和MethodA2不能同时使用
-
MethodB1和MethodB2不能同时使用
-
MethodA1/2可以与MethodB1/2同时使用。
如果我们在每个方法中使用 lock(this)
,我们也将排除MethodA1/2与MethodB1/2同时运行。
通过创建2个锁定对象(lockAMethods,lockBMethods),我们现在可以更细粒度地实现锁定。
- 在MethodA1和MethodA2中,我们将使用 "
lock(lockAMethods)
",以确保A1和A2方法不能同时运行。 - 在MethodB1和B2中,我们将使用
"lock(lockBMethods)
",以确保B1和B2方法不能同时运行。
但是,我们可以同时lock(lockAMethods)
和lock(lockBMethods)
。 因此,我们现在可以同时运行MethodA1/2和MethodB1/2。
希望这有所帮助,