Monitor或Lock(this) {}形式實際上調用的是windows底層的CRITICAL_SECTION詳見這裡.臨界區在單核下是效能最好的鎖,我boss曾做過多次嘗試都無法超過這個鎖的效能只能達到接近.但是這個鎖在多核下表現並不理想,因為它是這樣實現的(我boss查看了彙編)在多核下它會先做50次自旋在鎖.可能ms的初衷是在多U情況下一個線程做自旋的時候另一個U就把背景工作執行緒的工作做完了.這樣效能會很高.但是在多核下效果不佳我覺得和作業系統的調度器實現有關.所以我這個鎖的想法就是去掉50次無意義的自旋不浪費CPU的周期這樣效率自然會提升. 我boss給這個鎖起名叫Unique意思就是只有一個線程可以進入.他的實現仿照CRITICAL_SECTION,第一個進入鎖的將引用計數從零置一,後面進入的線程增加引用計數並阻塞,推出鎖時只要引用計數大於零就喚醒一個阻塞的線程.代碼如下:
public class Unique
...{
int _useCount = 0;
Event_Trigger _trigger = new Event_Trigger();
public override void Lock()
...{
if( InterLocked.Increase(ref this._useCount) != 1 )
...{
this._trigger.Wait();
}
}
public override bool Try_Lock()
...{
return InterLocked.CompareExchange(ref this._useCount, 1, 0) == 0;
}
public override void UnLock()
...{
if(InterLocked.Decrement(ref this._useCount) > 0)
this._trigger.Post();
}
public override void Release()
...{
this._trigger.Close();
}
};
其中的Event_Trigger在我的上篇文章有介紹,Event_Trigger就是Semaphore,Wait()相當於WaitOne(),Post()相當於Release().在這個鎖中引用計數useCount是個臨界條件我們可以把它看成是一個並發事件,如果lock的時候大於1就阻塞,unlock的時候大於0就喚醒.這個事件必然會發生所以就讓它發生吧,不需要用絕對時間點的方式進行多次判斷.