使用对象而不是 this 来获取锁 - 线程化

27 浏览
0 Comments

使用对象而不是 this 来获取锁 - 线程化

这个问题已经有答案了:

为什么lock(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日
0
0 Comments

区别在于锁定的粒度。

当锁定一个对象时(简化),实例上会设置一个位。任何试图锁定同一实例的其他人都会陷入等待状态,直到由其他人释放锁定。

在许多情况下,对象上的方法可以同时使用(即并行)。如果该方法还使用 '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。

希望这有所帮助,

0
0 Comments

这两种情况将具有完全相同的效果。其中一个区别是其他对象无法看到thisLock,因此您可以确保没有其他内容将重用锁。如果您在this上锁定,则代码的另一部分也可以锁定Account的相同实例。

0