天天看點

.net線程同步的一些知識

同步的目的是防止多個線程通路共享資料的破壞問題,關鍵點:

處理同步是容易出錯的

通過鎖對性能會有影響

同一個時刻隻允許一個線程寫共享資源

<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&lt;T&gt; {

private readonly Object m_lock = new Object();

private readonly Queue&lt;T&gt; m_queue = new Queue&lt;T&gt;();

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>