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

1)Mutex:进程之间的同步(互斥量)。

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

当然,Monitor还有Pulse方法,该方法对于锁定同一个对象的时候,允许其它线程进入准备区,同时配合Wait方法(Wait将自己暂时退出)。某种情况下可以代替信号量(ManualResetEvent),考察以下例子(来源:http://bbs.csdn.net/topics/380095508):

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命名空间下)。用于多个程序域实例化某个类,使得该类的数据和方法都可以被同步(单个程序域也可以)。

值得注意的是:WaitHandler的WaitOne方法第二个参数在这里起作用。

示例代码:

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("=======");
        }
    }
}
posted @ 2015-01-13 11:13  Serviceboy  阅读(434)  评论(1编辑  收藏  举报