使用对象获取锁定,而不是使用 - 线程

时间:2013-12-03 13:18:04

标签: c# multithreading object locks

我正在尝试用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'会停止对象的所有操作,即其他线程调用其他方法?

我是否从根本上错过了解这一点,或者这是正确的结论?

3 个答案:

答案 0 :(得分:2)

两种情况都会产生完全相同的效果。一个区别是其他对象看不到thisLock,因此您可以确定没有其他对象可以重用锁。如果你锁定this,另一部分代码也可以锁定同一个帐户实例。

答案 1 :(得分:1)

区别在于锁定粒度。

当锁定对象时,(简化)在实例上设置了一个位。尝试锁定同一实例的任何其他人都将处于等待状态,直到锁定被另一个释放为止。

在许多情况下,可以同时使用对象上的方法(i.o.w.并行)。如果该方法也使用“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)。因此,我们现在可以在MethodB1 / 2的同时运行MethodA1 / 2。

希望这有帮助,

答案 2 :(得分:0)

你说

  

根据我的理解,我会认为'thisLock'只会停止   其他线程进入特定的代码区域。
  如果锁定'this'会停止对象的所有操作,即其他线程调用其他方法?

无论您在两个语句中使用lock(this)还是lock(thisLock),它都只会阻止其他线程进入该特定代码区域。
但作为一般惯例,始终建议不要使用 lock(this)而是创建另一个对象并在该对象上放置lock

编辑是的,因为Sriram Sakthivel已发表评论,他是绝对正确的,请阅读Why is lock(this) {...} bad?了解更多有关我们应该避免的问题lock(this)