为什么我们需要在c#中锁定和对象?

本文关键字:锁定 对象 我们 为什么 | 更新日期: 2023-09-27 18:16:26

这是我一直无法理解的。创建一个获得lock ed的虚拟对象似乎是一种hack,就像示例

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

是否相等?

为什么我们需要在c#中锁定和对象?

传递给lock的实例用于识别临界区

在你的代码中可能有任意数量的不相关的临界区,每个临界区都将锁定一个不同的对象。一个无参数的lock语句,就像你建议的那样,将无法区分许多临界区。

编辑

虽然这看起来很明显,但值得注意的是,每个需要进入给定临界区的部分都必须访问被锁定的对象。因此,这不是在lock语句之前和在相同范围内创建任意实例的问题。

我认为混乱在于锁关键字在做什么。这并不是说只有一个线程可以进入这段代码,而是说了两件事:

  1. 只有一个线程可以进入这段代码谁拥有thisLock
  2. 任何其他被thisLock锁定的section也不允许被任何线程进入,除了这个线程,因为这个线程有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,正在用第一个锁做退出部分时,任何其他线程也不允许使用lock(thisLock)的类的所有其他部分进入。但是,允许其他线程进入带有thisLock2的部分。

考虑lock关键字的最好方法,至少在我学习的时候它帮助了我,就是把它想象成一个人质。换句话说,当执行代码的某些部分时,它需要在示例中接受一个人质(thisLock)。因此,一旦thisLock被作为人质,没有其他线程可以将其作为人质,直到该线程释放人质。因此,所有其他需要同样的人质的代码段将不可用。