執行緒同步(C#程式設計指南)

最美的回憶發表於2017-11-29

在應用程式中使用多個執行緒的一個好處是每個執行緒都可以非同步執行。對於 Windows 應用程式,耗時的任務可以在後臺執行,而使應用程式視窗和控制元件保持響應。對於伺服器應用程式,多執行緒處理提供了用不同執行緒處理每個傳入請求的能力。否則,在完全滿足前一個請求之前,將無法處理每個新請求。

然而,執行緒的非同步特性意味著必須協調對資源(如檔案控制程式碼、網路連線和記憶體)的訪問。否則,兩個或更多的執行緒可能在同一時間訪問相同的資源,而每個執行緒都不知道其他執行緒的操作。結果將產生不可預知的資料損壞。

對於整數資料型別的簡單操作,可以用 Interlocked 類的成員來實現執行緒同步。對於其他所有資料型別和非執行緒安全的資源,只有使用本主題中的結構才能安全地執行多執行緒處理。

有關多執行緒程式設計的背景資訊,請參見:

使用執行緒處理(C# 程式設計指南)

託管執行緒處理基本知識

使用執行緒和執行緒處理

託管執行緒處理的最佳做法

lock 關鍵字
public void Function()
{

System.Object lockThis = new System.Object();
lock(lockThis)
{
    // Access thread-sensitive resources.
}

}
提供給 lock 關鍵字的引數必須為基於引用型別的物件,該物件用來定義鎖的範圍。在上例中,鎖的範圍限定為此函式,因為函式外不存在任何對該物件的引用。嚴格地說,提供給 lock 的物件只是用來唯一地標識由多個執行緒共享的資源,所以它可以是任意類例項。然而,實際上,此物件通常表示需要進行執行緒同步的資源。例如,如果一個容器物件將被多個執行緒使用,則可以將該容器傳遞給 lock,而 lock 後面的同步程式碼塊將訪問該容器。只要其他執行緒在訪問該容器前先鎖定該容器,則對該物件的訪問將是安全同步的。

通常,最好避免鎖定 public 型別或鎖定不受應用程式控制的物件例項。例如,如果該例項可以被公開訪問,則 lock(this) 可能會有問題,因為不受控制的程式碼也可能會鎖定該物件。這可能導致死鎖,即兩個或更多個執行緒等待釋放同一物件。出於同樣的原因,鎖定公共資料型別(相比於物件)也可能導致問題。鎖定字串尤其危險,因為字串被公共語言執行庫 (CLR)“暫留”。這意味著整個程式中任何給定字串都只有一個例項,就是這同一個物件表示了所有執行的應用程式域的所有執行緒中的該文字。因此,只要在應用程式程式中的任何位置處具有相同內容的字串上放置了鎖,就將鎖定應用程式中該字串的所有例項。因此,最好鎖定不會被暫留的私有或受保護成員。某些類提供專門用於鎖定的成員。例如,Array 型別提供 SyncRoot。許多集合型別也提供 SyncRoot。

監視器
與 lock 關鍵字類似,監視器防止多個執行緒同時執行程式碼塊。Enter 方法允許一個且僅一個執行緒繼續執行後面的語句;其他所有執行緒都將被阻止,直到執行語句的執行緒呼叫 Exit。這與使用 lock 關鍵字一樣。事實上,lock 關鍵字就是用 Monitor 類來實現的。例如:

lock 關鍵字可以用來確保程式碼塊完成執行,而不會被其他執行緒中斷。這是通過在程式碼塊執行期間為給定物件獲取互斥鎖來實現的。

lock 語句以關鍵字 lock 開頭,它有一個作為引數的物件,在該引數的後面還有一個一次只能由一個執行緒執行的程式碼塊。例如:
本文轉自jiahuafu部落格園部落格,原文連結http://www.cnblogs.com/jiahuafu/archive/2010/06/03/1750722.html如需轉載請自行聯絡原作者

jiahuafu


相關文章