2016-11-05 73 views
5

这是我从未理解的东西。它似乎像一个黑客创建一个虚拟对象,得到lock版,喜欢的例子为什么我们需要在C#中锁定和对象?

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; 
     } 
    } 
} 

https://msdn.microsoft.com/en-us/library/c5kehkcz.aspx

为什么不能在语言的设计者让这个

class Account 
{ 
    decimal balance; 

    public void Withdraw(decimal amount) 
    { 
     lock 
     { 
      if (amount > balance) 
      { 
       throw new Exception("Insufficient funds"); 
      } 
      balance -= amount; 
     } 
    } 
} 

会相同呢?

+5

@Sayse一点都没有,否则没有人会明白如何使用'lock'。为什么需要'lock'语句需要传递一个参数的原因是非常清楚的,如果作者不理解这些原因,这个问题是非常有效的。 – rucamzu

+0

@rucamzu - 我想我误读了这个问题 – Sayse

回答

7

传递给lock的实例服务于标识关键部分

您的代码中可能有任何数量的不相关的关键部分,并且每个部分都会锁定不同的对象。一个无参数的lock声明,您所建议的声明将不能区分许多关键部分。

编辑

虽然这似乎是显而易见的,但值得注意的是,每一个部分需要进入一个给定的关键部分必须能够访问锁定的对象。所以这不是在lock声明之前和在相同范围内创建任意实例的问题。

+0

是的你说得对,我误解了它,我认为他不明白什么是锁定。感谢您的评论 – mybirthname

+0

@mybirthname完全没有问题。只是为了记录,我发现你的解释清楚而有用。 – rucamzu

0

我认为混淆在于锁关键字在做什么。这是不是说只有1个线程可以进入的代码段,但它是说两两件事:

  1. 只有一个线程可以进入的这部分代码谁拥有thisLock
  2. 被锁定与thisLock是任何其它部分除了这个线程外,也不允许任何线程进入,因为这个线程有thisLock。

你的建议只会做第一个,但不是两个。请看下面的例子:

class Account 
{ 
    decimal balance; 
    private Object thisLock = new Object(); 
    private Object thisLock2 = new Object(); 

    public void Withdraw(decimal amount) 
    { 
     lock (thisLock) 
     { 
      if (amount > balance) 
      { 
       throw new Exception("Insufficient funds"); 
      } 
      balance -= amount; 
     } 

     // more code here but no locking necessary... 

     lock(thisLock) 
     { 
      // only one thread can enter here who has thisLock 
     } 

     lock (thisLock2) 
     { 
      // If T1 (thread1) is working with thisLock, T2 can come here since it has nothing to do 
      // with thisLock. 
     } 
    } 

    public void AnotherOperation() 
    { 
     lock (thisLock) 
     { 
      // code here... 
     } 
    } 

    public void YetAnotherOperation() 
    { 
     lock (thisLock) 
     { 
      // code here... 
     } 
    } 
} 

当一个线程,说T1,做与第一锁取出部,与锁(thisLock)之类的所有其他部分都不得用任何其他线程的入口,以及。但是,带有thisLock2的部分可以由其他线程输入。

想到lock关键字的最好方法,至少它在我学习的时候帮助了我,把它当作人质。换句话说,当代码的某些部分正在执行时,它需要在你的例子中使用人质(thisLock)。因此,一旦thisLock被视为人质,其他线程就不能将其作为人质,直到该线程释放人质。因此,所有其他需要相同人质的代码段也不可用。

相关问题