Mutex,Monitor,lock,MethodImplAttribute,SynchronizedAttribute的用法差別

1)Mutex:進程之間的同步(互斥量)。this

2)lock/Monitor……:線程同步。其中lock是Monitor的簡化版本(直接生成try{Monitor.Enter(……)}finally{Monitor.Exit(……);}方法。spa

固然,Monitor還有Pulse方法,該方法對於鎖定同一個對象的時候,容許其它線程進入準備區,同時配合Wait方法(Wait將本身暫時退出)。某種狀況下能夠代替信號量(ManualResetEvent),考察如下例子(來源:http://bbs.csdn.net/topics/380095508):.net

class MyManualEvent
{
    private object lockObj = new object();
    private bool hasSet = false;
 
    public void Set()
    {
        lock (lockObj)                   //排隊準備領到開鎖的鑰匙
        {
            hasSet = true;
            Monitor.PulseAll(lockObj);   //通知其餘排隊人先拿鑰匙開鎖
        }
    }
    public void WaitOne()
    {
        lock (lockObj)                  //排隊準備領取開鎖的鑰匙
        {
            while (!hasSet)
            {
                Monitor.Wait(lockObj);  //等通知,這樣能夠拿到鑰匙開鎖了
            }
        }
    }
}
class Program
{
    static MyManualEvent myManualEvent = new MyManualEvent();
    static void Main(string[] args)
    {
        ThreadPool.QueueUserWorkItem(WorkerThread, "A");
        ThreadPool.QueueUserWorkItem(WorkerThread, "B");
        Console.WriteLine("Press enter to signal the green light");
        Console.ReadLine();
        myManualEvent.Set();
        ThreadPool.QueueUserWorkItem(WorkerThread, "C");
        Console.ReadLine();
    }
    static void WorkerThread(object state)
    {
        myManualEvent.WaitOne();
        Console.WriteLine("Thread {0} got the green light...", state);
    }
}

3)MethodImpl:是一個特性,在System.Runtime.CompilerServices下,等同於lock。在做用於一個類方法的時候=lock(this),做用於一個靜態方法等同於lock(typeof(某個類))。線程

4)SynchronizedAttribute(在System.Runtime.Remoting.Contexts命名空間下)。用於多個程序域實例化某個類,使得該類的數據和方法均可以被同步(單個程序域也能夠)。code

值得注意的是:WaitHandler的WaitOne方法第二個參數在這裏起做用。對象

示例代碼:blog

namespace ConsoleApplication1
{
    [Synchronization(true)] class My:ContextBoundObject
    {
        static void Main(string[] args)
        {
            My my = new My();
            ThreadPool.QueueUserWorkItem(my.FuncA);
            ThreadPool.QueueUserWorkItem(my.FuncA);

            Console.ReadLine();
        }

        AutoResetEvent myEvent = new AutoResetEvent(false);

        public void FuncA(object state)
        {
            Console.WriteLine("Thread id is:"+Thread.CurrentThread.ManagedThreadId);
            myEvent.WaitOne(2000, false);   //改爲true你發現會有第二個線程忽然插入並執行
            Console.WriteLine("=======");
        }
    }
}
相關文章
相關標籤/搜索