[c#] 鎖(locker)和鎖之間的區別(variable_which_I_am_using)



3 Answers

理解lock(m_Hash)不會阻止其他代碼使用散列,這一點很重要。 它只阻止其他代碼運行,也使用m_Hash作為其鎖定對象。

使用選項A的一個原因是因為類可能具有在鎖定語句中使用的私有變量。 只使用一個對象來鎖定對所有對象的訪問,而不是嘗試使用更細粒度的鎖來將訪問權限鎖定到需要的成員上會容易得多。 如果您嘗試使用更細粒度的方法,則在某些情況下可能需要使用多個鎖,然後您需要確保始終按照相同的順序來避免死鎖。

使用選項A的另一個原因是因為可能會在類的外部訪問對m_Hash的引用。 也許你有一個公共財產提供訪問權限,或者你可以聲明它是受保護的派生類可以使用它。 在任何一種情況下,一旦外部代碼有引用,外部代碼可能會用它來進行鎖定。 這也造成了死鎖的可能性,因為你無法控製或知道鎖定的順序。

Question

我正在使用C#&.NEt 3.5。 OptionA和OptionB有什麼區別?

class MyClass
{
    private object m_Locker = new object();
    private Dicionary<string, object> m_Hash = new Dictionary<string, object>();

    public void OptionA()
    {
        lock(m_Locker){ 
          // Do something with the dictionary
        }
    }

    public void OptionB()
    {
        lock(m_Hash){ 
          // Do something with the dictionary
        }
    }       
}

我開始涉足線程(主要是為多線程應用程序創建一個緩存,不使用HttpCache類,因為它沒有連接到網站),我在很多示例中看​​到了OptionA語法在線查看,但我不明白什麼,如果有的話,通過OptionB完成的原因。




那麼,這取決於你想鎖定什麼(做成線程安全)。

通常我會選擇OptionB來提供對m_Hash的線程安全訪問。 在OptionA中,我將用於鎖定值類型,它不能用於鎖,或者我有一組需要同時鎖定的對象,但是我不用鎖來鎖定整個實例lock(this)




這不是你所“鎖定”的,它是包含在鎖定之間的代碼,這些鎖定很重要,而且可以防止被執行。

如果一個線程在任何對像上取出一個lock(),它將阻止其他線程獲取對同一個對象的鎖,從而阻止第二個線程執行大括號之間的代碼。

所以這就是為什麼大多數人只是創建一個垃圾對象來鎖定,它阻止了其他線程獲得同一個垃圾對象的鎖。




在訪問使用m_Locker鎖定m_hash的m_hash時,只要在所有的代碼中選擇OptionA即可。

現在想像一下這種情況。 你鎖定對象。 這個對像在你調用的函數中有一個lock(this)代碼段。 在這種情況下,這是一個肯定的不可恢復的死鎖




Related