公共語言架構提供了三種策略來同步訪問實例和靜態方法以及實例屬性,這三種策略是:
1. 同步上下文
2. 同步代碼區域
3. 手動同步
同步上下文
上下文是一系列對象集合在執行時常見的屬性或者使用規范。可以被添加的上下文屬性包括同步,線程關聯以及事務。簡而言之,一個上下文是由一些相似的對象組成。在同步策略中,我們使用SynchronizationAttribute 類來為ContextBoundObject 對象提供簡單、原子化同步。上下文中綁定到上下文規則上的對象被稱作上下文綁定對象。.NET 自動地使用一個同步鎖來關聯這個對象,在每次方法調用之前鎖住並在方法返回時釋放鎖(允許其他競爭線程訪問對象)。這是對生產力的巨大提高,因為線程同步和並發管理是一個開發人員所需面對的最困難的任務(沒有之一)。
SynchronizationAttribute 類對那些沒有手動處理同步問題經驗的開發人員來說是很有用的,因為它囊括了屬性所應用到的類的實例變量,實例方法以及實例字段。它不處理靜態字段和靜態方法的同步。如果你不得不同步特殊代碼塊的話那么它也不起作用;為了便於使用你不得不同步整個對象。使用System.EnterpriseServices編程時SynchronizationAttribute 會非常有用,因為它可以將屬於一個上下文(或者一個事務)的對象通過COM+運行時組合到一起。
回到我們的Account例子,我們可以通過使用SynchronizationAttribute 來讓我們使用偽代碼實現的Account類支持線程安全。下面是具體的例子:
/************************************* /* Copyright (c) 2012 Daniel Dong * * Author:Daniel Dong * Blog: www.cnblogs.com/danielWise * Email: guofoo@163.com * */ using System; using System.Collections.Generic; using System.Text; using System.EnterpriseServices; namespace SimpleThread { [SynchronizationAttribute(SynchronizationOption.Required)] public class Account : ContextBoundObject { public ApprovedOrNot Withdraw(Amount) { //1. Check the Account Balance //2. Update the Account with the new balance //3. Send approval to the ATM } } }
SynchronizationAttribute 類有兩個構造函數;一個無參構造函數和一個以SynchronizationOption枚舉作為參數的構造函數。我們使用默認的無參構造函數,SynchronizationOption枚舉的默認值是SynchronizationOption.Required. 其他的枚舉值是Disabled, NotSupported, RequiredNew 和 Supported. 下面列舉出了這些選項。
同步代碼區域
第二個同步策略主要關注特定代碼區域。這些特定的代碼區域是方法中改變對象狀態或者更新其他資源(數據庫或者文件)的關鍵代碼片段。在這部分我們將看看Monitor 和 ReaderWriterLock 類。
Monitors
Monitors 使用Monitor.Enter() 方法來獲得一個鎖並使用鎖來同步代碼部分,然后使用Monitor.Exit()方法來釋放鎖。一個鎖的概念通常用來解釋Monitor類。一個線程獲得一個鎖,而其他線程一直等待鎖被釋放。一旦鎖被一個代碼區域獲得,你可以在Monitor.Enter() 和Monitor.Exit() 代碼塊中使用如下方法:
Wait() - 這個對象在一個對象上釋放鎖並阻塞當前線程直到它獲得到鎖
Pulse() - 這個方法通知在隊列中等待的指定線程對象的狀態已經發生改變
PulseAll() - 這個方法通知在隊列中等待的所有線程對象的狀態已經發生改變
下一篇我們將會介紹Monitor.Enter() 和 Monitor.Exit() 方法…