29.3.1 易變構造
當線程通過共享內存互相通信時,調用Volatile.Write來寫入最后一個值,調用Volatile.Read來讀取第一個值
public class ThreadsSharingData{private volatile int flag = 0;private int value = 0;public void Thread1(){//注意在將1寫入flag之前,必須先將5寫入valuevalue = 5;flag = 1;}public void Thread2(){//注意在value必須在讀取了flag之后才能讀取if (flag == 1)Console.WriteLine(value);}}
設計模式23模式介紹??29.3.2 互鎖構造
internal sealed class AsyncCoordinator{private int m_opCount = 1;private int m_statusReported = 0;private Action<CoordinatorStatus> m_callback;private Timer m_timer;public void AboutToBegin(int opsToAdd = 1){Interlocked.Add(ref m_opCount, opsToAdd);}public void JuseEnded(){if (Interlocked.Decrement(ref m_opCount) == 0)ReportStatus(CoordinatorStatus.AllDone);}public void AllBegun(Action<CoordinatorStatus> callback, int timeout = Timeout.Infinite){m_callback = callback;if (timeout != Timeout.Infinite)m_timer = new Timer(TimeExpired, null, timeout, Timeout.Infinite);JuseEnded();}private void TimeExpired(object o){ReportStatus(CoordinatorStatus.Timeout);ReportStatus(CoordinatorStatus.Cancel);}private void ReportStatus(CoordinatorStatus status){if (Interlocked.Exchange(ref m_statusReported, 1) == 0)m_callback(status);}public enum CoordinatorStatus{AllDone, Timeout, Cancel}}
?29.3.3 實現簡單的自旋鎖
class Program{private static SimpleSpinLock ssl = new SimpleSpinLock();static void Main(){ssl.Enter();//一次只有一個線程才能進入這里訪問資源 ssl.Leave();Console.ReadKey();}}internal struct SimpleSpinLock{private int m_resourceInuse; //0=false,1=truepublic void Enter(){while (true){//總是將資源設置為正在使用//只有未使用變成正在使用才會返回if (Interlocked.Exchange(ref m_resourceInuse, 1) == 0)return;//添加黑科技 }}public void Leave(){Volatile.Write(ref m_resourceInuse, 0);}}
29.3.4?Interlocked anything
單用戶模式修改密碼??
delegate int Morpher<TResult, TArgument>(int startValue, TArgument argument, out TResult morphResult);private static TResult Morph<TResult, TArgument>(ref int target, TArgument argument, Morpher<TResult, TArgument> morpher){TResult morphResult;int currentVal = target, startVal, desiredVal;do{startVal = currentVal;desiredVal = morpher(startVal, argument, out morphResult);currentVal = Interlocked.CompareExchange(ref target, desiredVal, startVal);}while (startVal != currentVal);return morphResult;}private static int Maximun(ref int target, int value){int currentVal = target, startVal, desiredVal;//不要在循環中訪問目標target,除非想要改變它時另一個線程也在動它do{//記錄這一次循環的起始值startValstartVal = currentVal;//基于startVal和value計算desiredValdesiredVal = Math.Max(startVal, value);//注意:線程在這里可能被“搶占”,所以以下代碼不是原子性的//if (target == startVal) target = desiredVal;//使用原子性的方法,返回在target在(可能)被方法修改之前的值currentVal = Interlocked.CompareExchange(ref target, desiredVal, startVal);}//如果target的值在這一次循環迭代中被其它線程改變,就重復while (startVal != currentVal);return desiredVal;}
?