同步的目的是防止多個線程通路共享資料的破壞問題,關鍵點:
處理同步是容易出錯的
通過鎖對性能會有影響
同一個時刻隻允許一個線程寫共享資源
<b>一些建議</b>
避免靜态字段共享資料(隻讀除外)
建立的對象線上程之間不傳遞使用,也不需要同步
最好使用值類型,線程操作的是這些類型的拷貝,是以不需要同步
<b>使用者模式、核心模式基元構造</b>
優點
缺點
例子
基元使用者模式
使用特殊的CPU指令,速度比核心模式快
OS不能偵測到線程的阻塞,會多次反複排程
易失
互鎖構造
Interlocked construct
[都要求傳遞對“包含一個簡單資料類型的一個變量”的引用]
基元核心模式
Windows系統自身提供的
會阻塞線程,不會浪費CPU
使用者态切換到核心态有性能損失
事件、信号量(以上兩者基礎上的如互斥體)
信号量是由核心維護的Int32變量
互斥體和AutoResetEvent(或計數為1的Semaphore)相似
<b>混合線程同步構造:</b>一般情況下,通過合并使用者模式和核心模式同步構造,沒有線程競争時,提供了核心模式的性能;競争時提供了核心模式的優點。
<b>System.Threading</b><b>下的混合線程同步構造</b>
ManualResetEventSlim、SemaphoreSlim、ReaderWriterLockSlim特别處在于它們都在使用者模式中“自旋”,而且都推遲到發生第一次競争時,才建立核心模式的構造
<b>Monitor</b><b>的使用:</b>
每個對象都使用私有的鎖
///防止反複測試條件的浪費CPU的一個方法
public sealed class SynchronizedQueue<T> {
private readonly Object m_lock = new Object();
private readonly Queue<T> m_queue = new Queue<T>();
public void Enqueue(T item) {
Monitor.Enter(m_lock);
m_queue.Enqueue(item);
Monitor.PulseAll(m_lock); // Wakeup any/all waiters 激發
Monitor.Exit(m_lock);
}
///在有一個可供處理的資料項之前,試圖出隊一個資料項的線程會一直阻塞
public T Dequeue() {
// Loop waiting for condition (queue not empty)
while (m_queue.Count == 0)
Monitor.Wait(m_queue);//釋放鎖所有權,等待激發條件
<a></a>
T item = m_queue.Dequeue();
return item;
}
<b>單例模式和Lazy</b><b>中使用的鎖</b>
public Lazy(LazyThreadSafetyMode mode)
LazyInitializer.EnsureInitialized
把對象的初始化放到需要的時刻,以減少内容的占用
更詳細的鎖的使用和處理參考:
圖書 Clr Via C#
<a href="http://ys-f.ys168.com/?CLR_via_CSharp_3rd_Edition_Code_by_Jeffrey_Richter.zip_55bism1e0e7bkisjthit2bso0cm5bs4bs1b5bktnql0c0bu22f05f12z">http://ys-f.ys168.com/?CLR_via_CSharp_3rd_Edition_Code_by_Jeffrey_Richter.zip_55bism1e0e7bkisjthit2bso0cm5bs4bs1b5bktnql0c0bu22f05f12z</a>