C# 使用对象而不是此线程获取锁

C# 使用对象而不是此线程获取锁,c#,multithreading,object,locks,C#,Multithreading,Object,Locks,我正在尝试学习C#中的线程,我在几篇文章中看到了一些东西,但我不确定我是否完全理解它: 在给定的两个示例中,在“this”和“thisLock”上获得锁的根本区别是什么 例1: class Account { decimal balance; private Object thisLock = new Object(); public void Withdraw(decimal amount) {

我正在尝试学习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”上获得锁会停止对象上的所有操作,即其他线程对其他方法的调用


我根本不理解这一点,还是这是正确的结论?

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

您说过

根据我的理解,我会认为“这锁”只会停下来 其他线程无法进入特定的代码区域。
是否因为在“this”上获得锁会停止对象上的所有操作,即其他线程对其他方法的调用

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


编辑是的,正如斯里拉姆·萨基维勒(Sriram Sakthivel)所评论的,他是绝对正确的,请阅读更多信息,了解我们为什么应该避免锁定(此)不同之处在于锁定粒度

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

在许多情况下,可以同时使用对象上的方法(i.o.w.并行)。锁定整个对象(this)将排除任何其他方法的使用,如果该方法也使用“
lock(this)

因为lock可以用于任何引用类型,所以我们可以创建“lock”对象。我们在排除的基础上实现“
锁(lockObject)

例如,

  • 方法1和方法2不能同时使用
  • 方法B1和方法B2不能同时使用

  • 方法1/2可与方法1/2同时使用

如果我们在每个方法上都使用
锁(this)
,那么我们也将排除MethodA1/2与MethodB1/2同时运行

通过创建2个锁对象(LockMethods、lockBMethods),我们现在可以实现更细粒度的锁

  • 在MethodA1和MethodA2中,我们将使用“
    lock(lockAMethods)
    ”来确保A1和A2方法不能同时运行
  • 在方法B1和B2中,我们将使用
    “lock(lockBMethods)
    ”来确保B1和B2方法不能同时运行
但是,我们可以同时
锁定(lockAMethods)
锁定(lockBMethods)
。因此,我们现在可以同时运行MethodA1/2和MethodB1/2


希望这有帮助,

确实有帮助吗?斯里拉姆的建议就是答案——要清楚地说,
lock(this)
lock(somethingElse)
没有任何区别。不要使用
lock(this)
的建议必须放在正确的角度。框架设计指南对此提出了反对意见,因为从框架的角度来看,这是不好的。框架的使用者总是可以锁定框架中某个类型的实例,这可能会意外导致死锁。在编写LOB应用程序时,可以完全控制编写哪些代码,这可能不是什么大问题。我想说,在这种情况下,
lock(this)
是可以的,但在另一种类型的实例上使用锁实际上是不好的做法。修复了坏链接,您链接了当前问题的链接:)“您可以确保没有其他方法会重用锁”-只要该类中没有其他方法使用相同的锁对象。@CodeCaster:当然,但这是你——作为该课程的作者——完全可以控制的:——)